121291eeed
Build and Deploy to Kubernetes / build-and-deploy (push) Has been cancelled
Allow optional slug on create/update, generate from title with unique fallback, so BackOffice can publish posts without manual slug entry. Co-authored-by: Cursor <cursoragent@cursor.com>
102 lines
3.8 KiB
C#
102 lines
3.8 KiB
C#
using CMSMicroservice.Application.Common;
|
|
using CMSMicroservice.Application.Common.FileManager;
|
|
using CMSMicroservice.Application.Common.Interfaces;
|
|
using CMSMicroservice.Domain.Entities.Blog;
|
|
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace CMSMicroservice.Application.BlogPostCQ.Commands.UpdateBlogPost;
|
|
|
|
public class UpdateBlogPostCommandHandler : IRequestHandler<UpdateBlogPostCommand, Unit>
|
|
{
|
|
private readonly IApplicationDbContext _context;
|
|
private readonly IFileManager _fileManager;
|
|
private readonly ILogger<UpdateBlogPostCommandHandler> _logger;
|
|
|
|
public UpdateBlogPostCommandHandler(
|
|
IApplicationDbContext context,
|
|
IFileManager fileManager,
|
|
ILogger<UpdateBlogPostCommandHandler> logger)
|
|
{
|
|
_context = context;
|
|
_fileManager = fileManager;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<Unit> Handle(UpdateBlogPostCommand request, CancellationToken cancellationToken)
|
|
{
|
|
var post = await _context.BlogPosts.FirstOrDefaultAsync(x => x.Id == request.Id && !x.IsDeleted, cancellationToken)
|
|
?? throw new KeyNotFoundException($"مقاله با شناسه {request.Id} یافت نشد");
|
|
|
|
post.Title = request.Title.Trim();
|
|
|
|
if (!string.IsNullOrWhiteSpace(request.Slug))
|
|
{
|
|
post.Slug = await BlogSlugHelper.EnsureUniquePostSlugAsync(
|
|
_context,
|
|
BlogSlugHelper.NormalizeOptional(request.Slug)!,
|
|
post.Id,
|
|
cancellationToken);
|
|
}
|
|
else if (string.IsNullOrWhiteSpace(post.Slug))
|
|
{
|
|
var slug = BlogSlugHelper.ResolveForCreate(null, post.Title);
|
|
post.Slug = await BlogSlugHelper.EnsureUniquePostSlugAsync(
|
|
_context, slug, post.Id, cancellationToken);
|
|
}
|
|
post.Summary = request.Summary?.Trim();
|
|
post.HtmlContent = request.HtmlContent;
|
|
post.FeaturedImagePath = request.FeaturedImagePath;
|
|
post.FeaturedImageThumbnailPath = request.FeaturedImageThumbnailPath;
|
|
post.IsFeatured = request.IsFeatured;
|
|
post.SortOrder = request.SortOrder;
|
|
|
|
// آپلود تصویر شاخص (اگر فایل جدید ارسال شده باشد)
|
|
if (request.ImageFileBytes is { Length: > 0 })
|
|
{
|
|
var result = await _fileManager.UploadImageAsync(
|
|
"Images/BlogPosts",
|
|
request.ImageFileBytes,
|
|
request.ImageFileMime ?? "image/jpeg",
|
|
request.ImageFileName,
|
|
cancellationToken);
|
|
|
|
post.FeaturedImagePath = result.Main.Path;
|
|
post.FeaturedImageThumbnailPath = result.Thumbnail.Path;
|
|
}
|
|
|
|
// بروزرسانی دستهبندیها
|
|
var existingCategories = await _context.BlogPostCategories
|
|
.Where(x => x.BlogPostId == post.Id).ToListAsync(cancellationToken);
|
|
_context.BlogPostCategories.RemoveRange(existingCategories);
|
|
foreach (var categoryId in request.CategoryIds)
|
|
{
|
|
_context.BlogPostCategories.Add(new BlogPostCategory
|
|
{
|
|
BlogPostId = post.Id,
|
|
BlogCategoryId = categoryId
|
|
});
|
|
}
|
|
|
|
// بروزرسانی تگها
|
|
var existingTags = await _context.BlogPostTags
|
|
.Where(x => x.BlogPostId == post.Id).ToListAsync(cancellationToken);
|
|
_context.BlogPostTags.RemoveRange(existingTags);
|
|
foreach (var tagId in request.TagIds)
|
|
{
|
|
_context.BlogPostTags.Add(new BlogPostTag
|
|
{
|
|
BlogPostId = post.Id,
|
|
TagId = tagId
|
|
});
|
|
}
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
_logger.LogInformation("Blog post updated. Id: {Id}, Title: {Title}", post.Id, post.Title);
|
|
|
|
return Unit.Value;
|
|
}
|
|
}
|