2502cbbda2
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m44s
Payment Gateway: - Add PYMSPaymentService: IPaymentGatewayService via gRPC to PYMS microservice - Add ZarinPalPaymentService: direct ZarinPal integration (backup) - Register 'pyms' payment provider in DI ConfigureServices - Add PYMS proto files (pyms_transaction.proto, pyms_public_messages.proto) - Fix VerifyDiscountWalletCharge: pass 'OK' as status instead of Authority - Update appsettings: PaymentProvider=pyms, sandbox mode, merchant ID Blog System: - Add BlogCategory, BlogPost, BlogPostImage entities and CQRS - Add proto files and gRPC services for blog management - Add Mapster profiles for blog responses Content Management: - Add SitePage entity and CQRS for static pages - Add proto and gRPC service for site pages Image/File Management: - Add LocalFileManager with disk storage + base64 serving + FMS fallback - Add ImagePathResolverInterceptor for gRPC responses - Add ImageResolverService for explicit image resolution - Add UploadsController for public file serving with FMS fallback - Add PaymentCallbackController for discount order payment callbacks Database: - Add blog and content entity migrations - Remove ImagePath MaxLength constraints - Remove old FileManagementService (replaced by LocalFileManager)
89 lines
3.4 KiB
C#
89 lines
3.4 KiB
C#
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();
|
|
// حفظ slug قبلی اگر مقدار جدید خالی باشد
|
|
if (!string.IsNullOrWhiteSpace(request.Slug))
|
|
post.Slug = request.Slug.Trim().ToLower();
|
|
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;
|
|
}
|
|
}
|