diff --git a/VizhTalk.Learning.Application/CommandHandlers/CourseCommandHandler.cs b/VizhTalk.Learning.Application/CommandHandlers/CourseCommandHandler.cs index b5d7fc5..410766d 100644 --- a/VizhTalk.Learning.Application/CommandHandlers/CourseCommandHandler.cs +++ b/VizhTalk.Learning.Application/CommandHandlers/CourseCommandHandler.cs @@ -17,11 +17,11 @@ public class CreateCourseCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcC public async Task 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(); } } -public class UpdateCourseCommandHandler(IUnitOfWork unitOfWork) : ICommandHandler +public class UpdateCourseCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient) : ICommandHandler { - public Task Handle(UpdateCourseCommand request, CancellationToken cancellationToken) + public async Task 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(); } -} +} \ No newline at end of file diff --git a/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs b/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs index ebf60f1..eb5f96d 100644 --- a/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs +++ b/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs @@ -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); } diff --git a/VizhTalk.Learning.Application/Exceptions/CourseNotFoundException.cs b/VizhTalk.Learning.Application/Exceptions/CourseNotFoundException.cs new file mode 100644 index 0000000..4b87027 --- /dev/null +++ b/VizhTalk.Learning.Application/Exceptions/CourseNotFoundException.cs @@ -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") + { + } + } +} diff --git a/VizhTalk.Learning.Application/QueryHandlers/LanguageQueryHandler.cs b/VizhTalk.Learning.Application/QueryHandlers/LanguageQueryHandler.cs index 0ca263c..f987ccf 100644 --- a/VizhTalk.Learning.Application/QueryHandlers/LanguageQueryHandler.cs +++ b/VizhTalk.Learning.Application/QueryHandlers/LanguageQueryHandler.cs @@ -10,9 +10,14 @@ public class GetAllLanguageQueryHandler(IGenericDapper languageDapp public async Task 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 language { public async Task 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; diff --git a/VizhTalk.Learning.Domain/Entities/Language.cs b/VizhTalk.Learning.Domain/Entities/Language.cs index 0fea5b6..a4607d5 100644 --- a/VizhTalk.Learning.Domain/Entities/Language.cs +++ b/VizhTalk.Learning.Domain/Entities/Language.cs @@ -39,21 +39,21 @@ public class Language : Entity, 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; } diff --git a/VizhTalk.Learning.Domain/Entities/Media.cs b/VizhTalk.Learning.Domain/Entities/Media.cs index 2509abf..78f576f 100644 --- a/VizhTalk.Learning.Domain/Entities/Media.cs +++ b/VizhTalk.Learning.Domain/Entities/Media.cs @@ -34,4 +34,15 @@ public class Media : Entity 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; } diff --git a/VizhTalk.Services.Grpc.Learning/Proto/Courses/Commands.proto b/VizhTalk.Services.Grpc.Learning/Proto/Courses/Commands.proto index cb26ff4..ab160fc 100644 --- a/VizhTalk.Services.Grpc.Learning/Proto/Courses/Commands.proto +++ b/VizhTalk.Services.Grpc.Learning/Proto/Courses/Commands.proto @@ -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; } \ No newline at end of file diff --git a/VizhTalk.Services.Grpc.Learning/Proto/Courses/DTOs.proto b/VizhTalk.Services.Grpc.Learning/Proto/Courses/DTOs.proto index e437f07..7db57af 100644 --- a/VizhTalk.Services.Grpc.Learning/Proto/Courses/DTOs.proto +++ b/VizhTalk.Services.Grpc.Learning/Proto/Courses/DTOs.proto @@ -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; } diff --git a/VizhTalk.Services.Grpc.Learning/Proto/Languages/DTOs.proto b/VizhTalk.Services.Grpc.Learning/Proto/Languages/DTOs.proto index 44cd721..6897f25 100644 --- a/VizhTalk.Services.Grpc.Learning/Proto/Languages/DTOs.proto +++ b/VizhTalk.Services.Grpc.Learning/Proto/Languages/DTOs.proto @@ -8,6 +8,7 @@ import "Proto/Shared.proto"; message LanguageDTO { Id Id = 1; string title = 2; + string icon = 3; }