This commit is contained in:
2025-09-12 19:46:59 +04:30
parent c7d97fe9bd
commit a6d6506e38
9 changed files with 117 additions and 26 deletions
@@ -17,11 +17,11 @@ public class CreateCourseCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcC
public async Task<CourseDTO> Handle(CreateCourseCommand request, CancellationToken cancellationToken)
{
var language = await unitOfWork.Language.GetLanguageWithCoursesById(new LanguageId(request.Languageid), cancellationToken);
if(language == null)
if (language == null)
throw new LanguageNotFoundException();
var fileGroup = await unitOfWork.FileGroup.GetByFileGroupKey(FileGroupKey.ImageCourse);
if(fileGroup == null)
if (fileGroup == null)
{
var group = await cdnClient.CreateMediaGroupAsync(new CreateMediaGroupCommand()
{
@@ -44,18 +44,58 @@ public class CreateCourseCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcC
MediaGroupId = fileGroup.MediaGroupId,
}, cancellationToken: cancellationToken);
var media = Media.CreateNew(request.Image.Name,upload.ContentType, upload.Size, upload.MediaGroupMediaId, new EntityType(EntityTypeEnum.Course));
var course = language.AddCourse(request.Title, media, request.Description);
await unitOfWork.Language.UpdateAsync(language,cancellationToken);
var media = Media.CreateNew(request.Image.Name, upload.ContentType, upload.Size, upload.MediaGroupMediaId, new EntityType(EntityTypeEnum.Course));
var course = language.AddCourse(request.Title, media, request.Description);
await unitOfWork.Language.UpdateAsync(language, cancellationToken);
await unitOfWork.SaveChangeAsync(cancellationToken);
return course.Adapt<CourseDTO>();
}
}
public class UpdateCourseCommandHandler(IUnitOfWork unitOfWork) : ICommandHandler<UpdateCourseCommand, CourseDTO>
public class UpdateCourseCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient) : ICommandHandler<UpdateCourseCommand, CourseDTO>
{
public Task<CourseDTO> Handle(UpdateCourseCommand request, CancellationToken cancellationToken)
public async Task<CourseDTO> Handle(UpdateCourseCommand request, CancellationToken cancellationToken)
{
var language = await unitOfWork.Language.GetLanguageWithCoursesById(new LanguageId(request.Languageid), cancellationToken);
if (language == null)
throw new LanguageNotFoundException();
if (!language.Courses.Any(x => x.Id == new CourseId(request.Id)))
throw new CourseNotFoundException();
Media image = null;
if (request.Image != null)
{
var fileGroup = await unitOfWork.FileGroup.GetByFileGroupKey(FileGroupKey.ImageCourse);
var upload = await cdnClient.UploadFileAsync(new UploadFileCommand()
{
File = new UploadFile()
{
ContentType = request.Image.ContentType,
File = request.Image.File,
Name = request.Image.Name,
},
MediaGroupId = fileGroup.MediaGroupId,
}, cancellationToken: cancellationToken);
var media = await unitOfWork.Media.GetByIdAsync(language.Icon.Id);
if (media == null)
media = Media.CreateNew(request.Title, upload.ContentType, upload.Size, upload.MediaGroupMediaId, new EntityType(EntityTypeEnum.Language));
else
{
media.SetName(request.Image.Name);
media.SetContentType(request.Image.ContentType);
media.SetSize(upload.Size);
media.SetFileId(upload.MediaGroupMediaId);
}
image = media;
}
var course = language.UpdateCourse(new CourseId(request.Id), new CourseTitle(request.Title), request.Order, image,
string.IsNullOrEmpty(request.Description) ? null : new CourseDescription(request.Description));
await unitOfWork.Language.UpdateAsync(language, cancellationToken);
return course.Adapt<CourseDTO>();
}
}
}
@@ -87,8 +87,17 @@ public class UpdateLanguageCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrp
},
MediaGroupId = fileGroup.MediaGroupId
}, cancellationToken: cancellationToken);
var media = await unitOfWork.Media.GetByIdAsync(language.Icon.Id);
var media = Media.CreateNew(request.Title, upload.ContentType, upload.Size, upload.MediaGroupMediaId, new EntityType(EntityTypeEnum.Language));
if(media == null)
media = Media.CreateNew(request.Title, upload.ContentType, upload.Size, upload.MediaGroupMediaId, new EntityType(EntityTypeEnum.Language));
else
{
media.SetName(request.Icon.Name);
media.SetContentType(request.Icon.ContentType);
media.SetSize(upload.Size);
media.SetFileId(upload.MediaGroupMediaId);
}
language.SetIcon(media);
}
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VizhTalk.BuildingBlocks.Application.Exceptions;
namespace VizhTalk.Learning.Application.Exceptions
{
public class CourseNotFoundException : BaseException
{
public CourseNotFoundException() : base("course not found")
{
}
}
}
@@ -10,9 +10,14 @@ public class GetAllLanguageQueryHandler(IGenericDapper<LanguageDTO> languageDapp
public async Task<GetAllLanguageDTO> Handle(GetAllLanguageQuery request, CancellationToken cancellationToken)
{
var result = new GetAllLanguageDTO();
var sql = $"select * from Learning.Languages " +
$"where @Search is null or {nameof(LanguageDTO.Title)} like N'%@Search%' " +
$"order by createOn OFFSET {request.Pagination.Skip()} ROWS FETCH NEXT {request.Pagination.Take()} ROWS ONLY;";
var sql = $"select " +
$"lan.{nameof(Language.Title)} as {nameof(LanguageDTO.Title)}," +
$"lan.{nameof(Language.Id)} as {nameof(LanguageDTO.Id)}," +
$"m.FileId as {nameof(LanguageDTO.Icon)}" +
$" from Learning.Languages as lan " +
$"inner join Learning.Medias as m on m.{nameof(Media.Id)} = lan.iconId " +
$"where @Search is null or lan.{nameof(LanguageDTO.Title)} like N'%@Search%' " +
$"order by lan.{nameof(Language.CreateOn)} OFFSET {request.Pagination.Skip()} ROWS FETCH NEXT {request.Pagination.Take()} ROWS ONLY;";
var language = await languageDapper.GetAllAsync(sql, new { request.Pagination.Search });
result.Languages.AddRange(language);
@@ -23,7 +28,13 @@ public class GetLanguageByTitleQueryHandler(IGenericDapper<LanguageDTO> language
{
public async Task<LanguageDTO> Handle(GetLanguageByTitleQuery request, CancellationToken cancellationToken)
{
var sql = $"select * from Learning.Languages where Title = @{nameof(Language.Title)}";
var sql = $"select " +
$"lan.{nameof(Language.Title)} as {nameof(LanguageDTO.Title)}," +
$"lan.{nameof(Language.Id)} as {nameof(LanguageDTO.Id)}," +
$"m.FileId as {nameof(LanguageDTO.Icon)}" +
$" from Learning.Languages" +
$" inner join Learning.Medias as m on {nameof(Media.Id)} = lan.iconId " +
$" where Title = @{nameof(Language.Title)}";
var language = await languageDapper.GetAsync(sql, new { request.Title });
return language;
@@ -39,21 +39,21 @@ public class Language : Entity<LanguageId>, IAggregateRoot
_courses.Add(course);
return course;
}
public Course UpdateCourse(Course course)
public Course UpdateCourse(CourseId courseId,CourseTitle courseTitle,int order, Media? image, CourseDescription? courseDescription)
{
var _course = _courses.FirstOrDefault(x => x.Id == course.Id) ?? throw new CourseNotFoundException(Title);
if (course.Image != null)
_course.SetImage(course.Image);
_course.SetTitle(course.Title);
_course.SetDescription(course.Description);
var _course = _courses.FirstOrDefault(x => x.Id == courseId) ?? throw new CourseNotFoundException(Title);
if (image != null)
_course.SetImage(image);
_course.SetTitle(courseTitle);
_course.SetDescription(courseDescription);
if (_course.Order != course.Order)
if (_course.Order != order)
{
var orderCourses = _courses.Where(x => x.Id != course.Id)
var orderCourses = _courses.Where(x => x.Id != courseId)
.OrderBy(x => x.Order)
.ToList();
_course.SetOrder(_course.Order);
orderCourses.Insert(course.Order, _course);
orderCourses.Insert(order, _course);
}
return _course;
}
@@ -34,4 +34,15 @@ public class Media : Entity<MediaId>
Guid fileId,
EntityType type)
=> new(name, contentType, size, fileId, type);
public void SetFileId(Guid fileId)
=> FileId = fileId;
public void SetName(string name)
=> Name = name;
public void SetContentType(string contentType)
=> ContentType = contentType;
public void SetSize(int size)
=> Size = size;
public void SetEntityType(EntityType entityType)
=> EntityType = entityType;
}
@@ -17,6 +17,7 @@ message UpdateCourseCommand{
Id Id = 1;
string title = 2;
string description = 3;
optional UploadFile image = 4;
Id languageid = 5;
int32 order = 4;
optional UploadFile image = 5;
Id languageid = 6;
}
@@ -7,7 +7,9 @@ import "Proto/Shared.proto";
message CourseDTO {
Id Id = 1;
string title = 2;
Id languageId = 2;
string title = 3;
string image = 4;
}
@@ -8,6 +8,7 @@ import "Proto/Shared.proto";
message LanguageDTO {
Id Id = 1;
string title = 2;
string icon = 3;
}