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
@@ -52,10 +52,50 @@ public class CreateCourseCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcC
} }
} }
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 MediaGroupId = fileGroup.MediaGroupId
}, cancellationToken: cancellationToken); }, 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); 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) public async Task<GetAllLanguageDTO> Handle(GetAllLanguageQuery request, CancellationToken cancellationToken)
{ {
var result = new GetAllLanguageDTO(); var result = new GetAllLanguageDTO();
var sql = $"select * from Learning.Languages " + var sql = $"select " +
$"where @Search is null or {nameof(LanguageDTO.Title)} like N'%@Search%' " + $"lan.{nameof(Language.Title)} as {nameof(LanguageDTO.Title)}," +
$"order by createOn OFFSET {request.Pagination.Skip()} ROWS FETCH NEXT {request.Pagination.Take()} ROWS ONLY;"; $"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 }); var language = await languageDapper.GetAllAsync(sql, new { request.Pagination.Search });
result.Languages.AddRange(language); result.Languages.AddRange(language);
@@ -23,7 +28,13 @@ public class GetLanguageByTitleQueryHandler(IGenericDapper<LanguageDTO> language
{ {
public async Task<LanguageDTO> Handle(GetLanguageByTitleQuery request, CancellationToken cancellationToken) 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 }); var language = await languageDapper.GetAsync(sql, new { request.Title });
return language; return language;
@@ -39,21 +39,21 @@ public class Language : Entity<LanguageId>, IAggregateRoot
_courses.Add(course); _courses.Add(course);
return 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); var _course = _courses.FirstOrDefault(x => x.Id == courseId) ?? throw new CourseNotFoundException(Title);
if (course.Image != null) if (image != null)
_course.SetImage(course.Image); _course.SetImage(image);
_course.SetTitle(course.Title); _course.SetTitle(courseTitle);
_course.SetDescription(course.Description); _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) .OrderBy(x => x.Order)
.ToList(); .ToList();
_course.SetOrder(_course.Order); _course.SetOrder(_course.Order);
orderCourses.Insert(course.Order, _course); orderCourses.Insert(order, _course);
} }
return _course; return _course;
} }
@@ -34,4 +34,15 @@ public class Media : Entity<MediaId>
Guid fileId, Guid fileId,
EntityType type) EntityType type)
=> new(name, contentType, size, fileId, 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; Id Id = 1;
string title = 2; string title = 2;
string description = 3; string description = 3;
optional UploadFile image = 4; int32 order = 4;
Id languageid = 5; optional UploadFile image = 5;
Id languageid = 6;
} }
@@ -7,7 +7,9 @@ import "Proto/Shared.proto";
message CourseDTO { message CourseDTO {
Id Id = 1; 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 { message LanguageDTO {
Id Id = 1; Id Id = 1;
string title = 2; string title = 2;
string icon = 3;
} }