Files
CMS/src/CMSMicroservice.Application/BlogPostCQ/Commands/CreateBlogPost/CreateBlogPostCommandHandler.cs
T
masoodafar-web 2502cbbda2
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m44s
feat: integrate PYMS payment gateway, add blog/sitepage/image services, local file manager
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)
2026-02-15 23:01:16 +03:30

99 lines
3.5 KiB
C#

using CMSMicroservice.Application.Common.FileManager;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities.Blog;
using CMSMicroservice.Domain.Enums;
using MediatR;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.BlogPostCQ.Commands.CreateBlogPost;
public class CreateBlogPostCommandHandler : IRequestHandler<CreateBlogPostCommand, long>
{
private readonly IApplicationDbContext _context;
private readonly ICurrentUserService _currentUser;
private readonly IFileManager _fileManager;
private readonly ILogger<CreateBlogPostCommandHandler> _logger;
public CreateBlogPostCommandHandler(
IApplicationDbContext context,
ICurrentUserService currentUser,
IFileManager fileManager,
ILogger<CreateBlogPostCommandHandler> logger)
{
_context = context;
_currentUser = currentUser;
_fileManager = fileManager;
_logger = logger;
}
public async Task<long> Handle(CreateBlogPostCommand request, CancellationToken cancellationToken)
{
var currentUserId = _currentUser.UserId;
if (string.IsNullOrEmpty(currentUserId) || !long.TryParse(currentUserId, out var authorUserId))
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
var post = new BlogPost
{
Title = request.Title.Trim(),
Slug = string.IsNullOrWhiteSpace(request.Slug)
? $"post-{Guid.NewGuid():N}".Substring(0, 20)
: request.Slug.Trim().ToLower(),
Summary = request.Summary?.Trim(),
HtmlContent = request.HtmlContent,
FeaturedImagePath = request.FeaturedImagePath,
FeaturedImageThumbnailPath = request.FeaturedImageThumbnailPath,
Status = BlogPostStatus.Draft,
AuthorUserId = authorUserId,
IsFeatured = request.IsFeatured,
SortOrder = request.SortOrder,
ViewCount = 0
};
// آپلود تصویر شاخص (اگر فایل ارسال شده باشد)
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;
}
_context.BlogPosts.Add(post);
await _context.SaveChangesAsync(cancellationToken);
// افزودن دسته‌بندی‌ها
foreach (var categoryId in request.CategoryIds)
{
_context.BlogPostCategories.Add(new BlogPostCategory
{
BlogPostId = post.Id,
BlogCategoryId = categoryId
});
}
// افزودن تگ‌ها
foreach (var tagId in request.TagIds)
{
_context.BlogPostTags.Add(new BlogPostTag
{
BlogPostId = post.Id,
TagId = tagId
});
}
if (request.CategoryIds.Any() || request.TagIds.Any())
await _context.SaveChangesAsync(cancellationToken);
_logger.LogInformation(
"Blog post created. Id: {Id}, Title: {Title}, Author: {Author}",
post.Id, post.Title, authorUserId);
return post.Id;
}
}