Add validators and services for Product Galleries and Product Tags
- Implemented Create, Delete, Get, and Update validators for Product Galleries. - Added Create, Delete, Get, and Update validators for Product Tags. - Created service classes for handling Discount Categories, Discount Orders, Discount Products, Discount Shopping Cart, Product Categories, Product Galleries, and Product Tags. - Each service class integrates with CQRS for command and query handling. - Established mapping profiles for Product Galleries.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using MediatR;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.CreatePublicMessage;
|
||||
|
||||
/// <summary>
|
||||
/// دستور ایجاد پیام عمومی
|
||||
/// Admin میتواند پیام عمومی برای نمایش در داشبورد کاربران ایجاد کند
|
||||
/// </summary>
|
||||
public class CreatePublicMessageCommand : IRequest<long>
|
||||
{
|
||||
/// <summary>
|
||||
/// عنوان پیام (حداکثر 200 کاراکتر)
|
||||
/// </summary>
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// محتوای پیام (حداکثر 2000 کاراکتر)
|
||||
/// </summary>
|
||||
public string Content { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// نوع پیام
|
||||
/// </summary>
|
||||
public MessageType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// اولویت پیام
|
||||
/// </summary>
|
||||
public MessagePriority Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// تاریخ شروع نمایش
|
||||
/// </summary>
|
||||
public DateTime StartsAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// تاریخ پایان نمایش
|
||||
/// </summary>
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// لینک اختیاری
|
||||
/// </summary>
|
||||
public string? LinkUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// متن دکمه لینک
|
||||
/// </summary>
|
||||
public string? LinkText { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Entities.Message;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.CreatePublicMessage;
|
||||
|
||||
public class CreatePublicMessageCommandHandler : IRequestHandler<CreatePublicMessageCommand, long>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ICurrentUserService _currentUser;
|
||||
private readonly ILogger<CreatePublicMessageCommandHandler> _logger;
|
||||
|
||||
public CreatePublicMessageCommandHandler(
|
||||
IApplicationDbContext context,
|
||||
ICurrentUserService currentUser,
|
||||
ILogger<CreatePublicMessageCommandHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_currentUser = currentUser;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<long> Handle(CreatePublicMessageCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. بررسی Admin
|
||||
var currentUserId = _currentUser.UserId;
|
||||
if (string.IsNullOrEmpty(currentUserId))
|
||||
{
|
||||
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
|
||||
}
|
||||
|
||||
if (!long.TryParse(currentUserId, out var createdByUserId))
|
||||
{
|
||||
throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
|
||||
}
|
||||
|
||||
// 2. ایجاد PublicMessage
|
||||
var message = new PublicMessage
|
||||
{
|
||||
Title = request.Title.Trim(),
|
||||
Content = request.Content.Trim(),
|
||||
Type = request.Type,
|
||||
Priority = request.Priority,
|
||||
IsActive = true,
|
||||
StartsAt = request.StartsAt,
|
||||
ExpiresAt = request.ExpiresAt,
|
||||
CreatedByUserId = createdByUserId,
|
||||
ViewCount = 0,
|
||||
LinkUrl = request.LinkUrl?.Trim(),
|
||||
LinkText = request.LinkText?.Trim()
|
||||
};
|
||||
|
||||
_context.PublicMessages.Add(message);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Public message created successfully. Id: {Id}, Title: {Title}, Type: {Type}, CreatedBy: {CreatedBy}",
|
||||
message.Id,
|
||||
message.Title,
|
||||
message.Type,
|
||||
createdByUserId
|
||||
);
|
||||
|
||||
return message.Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.CreatePublicMessage;
|
||||
|
||||
public class CreatePublicMessageCommandValidator : AbstractValidator<CreatePublicMessageCommand>
|
||||
{
|
||||
public CreatePublicMessageCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.Title)
|
||||
.NotEmpty().WithMessage("عنوان پیام الزامی است")
|
||||
.MaximumLength(200).WithMessage("عنوان نمیتواند بیشتر از 200 کاراکتر باشد");
|
||||
|
||||
RuleFor(x => x.Content)
|
||||
.NotEmpty().WithMessage("محتوای پیام الزامی است")
|
||||
.MaximumLength(2000).WithMessage("محتوا نمیتواند بیشتر از 2000 کاراکتر باشد");
|
||||
|
||||
RuleFor(x => x.Type)
|
||||
.IsInEnum().WithMessage("نوع پیام نامعتبر است");
|
||||
|
||||
RuleFor(x => x.Priority)
|
||||
.IsInEnum().WithMessage("اولویت پیام نامعتبر است");
|
||||
|
||||
RuleFor(x => x.StartsAt)
|
||||
.NotEmpty().WithMessage("تاریخ شروع الزامی است")
|
||||
.LessThan(x => x.ExpiresAt).WithMessage("تاریخ شروع باید قبل از تاریخ پایان باشد");
|
||||
|
||||
RuleFor(x => x.ExpiresAt)
|
||||
.NotEmpty().WithMessage("تاریخ پایان الزامی است")
|
||||
.GreaterThan(DateTime.UtcNow).WithMessage("تاریخ پایان باید در آینده باشد");
|
||||
|
||||
RuleFor(x => x.LinkUrl)
|
||||
.MaximumLength(500).WithMessage("لینک نمیتواند بیشتر از 500 کاراکتر باشد")
|
||||
.When(x => !string.IsNullOrEmpty(x.LinkUrl));
|
||||
|
||||
RuleFor(x => x.LinkText)
|
||||
.MaximumLength(100).WithMessage("متن لینک نمیتواند بیشتر از 100 کاراکتر باشد")
|
||||
.When(x => !string.IsNullOrEmpty(x.LinkText));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using MediatR;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.DeletePublicMessage;
|
||||
|
||||
/// <summary>
|
||||
/// دستور حذف (soft delete) پیام عمومی
|
||||
/// Admin میتواند پیام را حذف کند
|
||||
/// </summary>
|
||||
public class DeletePublicMessageCommand : IRequest<Unit>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه پیام
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.DeletePublicMessage;
|
||||
|
||||
public class DeletePublicMessageCommandHandler : IRequestHandler<DeletePublicMessageCommand, Unit>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ICurrentUserService _currentUser;
|
||||
private readonly ILogger<DeletePublicMessageCommandHandler> _logger;
|
||||
|
||||
public DeletePublicMessageCommandHandler(
|
||||
IApplicationDbContext context,
|
||||
ICurrentUserService currentUser,
|
||||
ILogger<DeletePublicMessageCommandHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_currentUser = currentUser;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Unit> Handle(DeletePublicMessageCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. بررسی Admin
|
||||
var currentUserId = _currentUser.UserId;
|
||||
if (string.IsNullOrEmpty(currentUserId))
|
||||
{
|
||||
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
|
||||
}
|
||||
|
||||
if (!long.TryParse(currentUserId, out var userId))
|
||||
{
|
||||
throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
|
||||
}
|
||||
|
||||
// 2. بررسی وجود پیام
|
||||
var message = await _context.PublicMessages
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Id && !x.IsDeleted, cancellationToken);
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
throw new KeyNotFoundException($"پیام با شناسه {request.Id} یافت نشد");
|
||||
}
|
||||
|
||||
// 3. Soft Delete
|
||||
message.IsDeleted = true;
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Public message deleted successfully. Id: {Id}, DeletedBy: {DeletedBy}",
|
||||
message.Id,
|
||||
userId
|
||||
);
|
||||
|
||||
return Unit.Value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using MediatR;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.UpdatePublicMessage;
|
||||
|
||||
/// <summary>
|
||||
/// دستور ویرایش پیام عمومی
|
||||
/// Admin میتواند پیامهای منقضی نشده را ویرایش کند
|
||||
/// </summary>
|
||||
public class UpdatePublicMessageCommand : IRequest<Unit>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه پیام
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// عنوان پیام (حداکثر 200 کاراکتر)
|
||||
/// </summary>
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// محتوای پیام (حداکثر 2000 کاراکتر)
|
||||
/// </summary>
|
||||
public string Content { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// نوع پیام
|
||||
/// </summary>
|
||||
public MessageType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// اولویت پیام
|
||||
/// </summary>
|
||||
public MessagePriority Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// وضعیت فعال/غیرفعال
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// تاریخ شروع نمایش
|
||||
/// </summary>
|
||||
public DateTime StartsAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// تاریخ پایان نمایش
|
||||
/// </summary>
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// لینک اختیاری
|
||||
/// </summary>
|
||||
public string? LinkUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// متن دکمه لینک
|
||||
/// </summary>
|
||||
public string? LinkText { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.UpdatePublicMessage;
|
||||
|
||||
public class UpdatePublicMessageCommandHandler : IRequestHandler<UpdatePublicMessageCommand, Unit>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ICurrentUserService _currentUser;
|
||||
private readonly ILogger<UpdatePublicMessageCommandHandler> _logger;
|
||||
|
||||
public UpdatePublicMessageCommandHandler(
|
||||
IApplicationDbContext context,
|
||||
ICurrentUserService currentUser,
|
||||
ILogger<UpdatePublicMessageCommandHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_currentUser = currentUser;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Unit> Handle(UpdatePublicMessageCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. بررسی Admin
|
||||
var currentUserId = _currentUser.UserId;
|
||||
if (string.IsNullOrEmpty(currentUserId))
|
||||
{
|
||||
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
|
||||
}
|
||||
|
||||
if (!long.TryParse(currentUserId, out var userId))
|
||||
{
|
||||
throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
|
||||
}
|
||||
|
||||
// 2. بررسی وجود پیام
|
||||
var message = await _context.PublicMessages
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Id && !x.IsDeleted, cancellationToken);
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
throw new KeyNotFoundException($"پیام با شناسه {request.Id} یافت نشد");
|
||||
}
|
||||
|
||||
// 3. بهروزرسانی پیام
|
||||
message.Title = request.Title.Trim();
|
||||
message.Content = request.Content.Trim();
|
||||
message.Type = request.Type;
|
||||
message.Priority = request.Priority;
|
||||
message.IsActive = request.IsActive;
|
||||
message.StartsAt = request.StartsAt;
|
||||
message.ExpiresAt = request.ExpiresAt;
|
||||
message.LinkUrl = request.LinkUrl?.Trim();
|
||||
message.LinkText = request.LinkText?.Trim();
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Public message updated successfully. Id: {Id}, UpdatedBy: {UpdatedBy}",
|
||||
message.Id,
|
||||
userId
|
||||
);
|
||||
|
||||
return Unit.Value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Commands.UpdatePublicMessage;
|
||||
|
||||
public class UpdatePublicMessageCommandValidator : AbstractValidator<UpdatePublicMessageCommand>
|
||||
{
|
||||
public UpdatePublicMessageCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.Id)
|
||||
.GreaterThan(0).WithMessage("شناسه پیام نامعتبر است");
|
||||
|
||||
RuleFor(x => x.Title)
|
||||
.NotEmpty().WithMessage("عنوان پیام الزامی است")
|
||||
.MaximumLength(200).WithMessage("عنوان نمیتواند بیشتر از 200 کاراکتر باشد");
|
||||
|
||||
RuleFor(x => x.Content)
|
||||
.NotEmpty().WithMessage("محتوای پیام الزامی است")
|
||||
.MaximumLength(2000).WithMessage("محتوا نمیتواند بیشتر از 2000 کاراکتر باشد");
|
||||
|
||||
RuleFor(x => x.Type)
|
||||
.IsInEnum().WithMessage("نوع پیام نامعتبر است");
|
||||
|
||||
RuleFor(x => x.Priority)
|
||||
.IsInEnum().WithMessage("اولویت پیام نامعتبر است");
|
||||
|
||||
RuleFor(x => x.StartsAt)
|
||||
.NotEmpty().WithMessage("تاریخ شروع الزامی است")
|
||||
.LessThan(x => x.ExpiresAt).WithMessage("تاریخ شروع باید قبل از تاریخ پایان باشد");
|
||||
|
||||
RuleFor(x => x.ExpiresAt)
|
||||
.NotEmpty().WithMessage("تاریخ پایان الزامی است");
|
||||
|
||||
RuleFor(x => x.LinkUrl)
|
||||
.MaximumLength(500).WithMessage("لینک نمیتواند بیشتر از 500 کاراکتر باشد")
|
||||
.When(x => !string.IsNullOrEmpty(x.LinkUrl));
|
||||
|
||||
RuleFor(x => x.LinkText)
|
||||
.MaximumLength(100).WithMessage("متن لینک نمیتواند بیشتر از 100 کاراکتر باشد")
|
||||
.When(x => !string.IsNullOrEmpty(x.LinkText));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using MediatR;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetActiveMessages;
|
||||
|
||||
/// <summary>
|
||||
/// کوئری دریافت پیامهای فعال
|
||||
/// برای نمایش در داشبورد کاربران
|
||||
/// </summary>
|
||||
public class GetActiveMessagesQuery : IRequest<List<PublicMessageDto>>
|
||||
{
|
||||
// فیلتر اختیاری: فقط پیامهای با اولویت خاص
|
||||
public int? MinPriority { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetActiveMessages;
|
||||
|
||||
public class GetActiveMessagesQueryHandler : IRequestHandler<GetActiveMessagesQuery, List<PublicMessageDto>>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ILogger<GetActiveMessagesQueryHandler> _logger;
|
||||
|
||||
public GetActiveMessagesQueryHandler(
|
||||
IApplicationDbContext context,
|
||||
ILogger<GetActiveMessagesQueryHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<List<PublicMessageDto>> Handle(GetActiveMessagesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var query = _context.PublicMessages
|
||||
.Where(x => !x.IsDeleted
|
||||
&& x.IsActive
|
||||
&& x.StartsAt <= now
|
||||
&& x.ExpiresAt >= now);
|
||||
|
||||
// فیلتر اختیاری اولویت
|
||||
if (request.MinPriority.HasValue)
|
||||
{
|
||||
query = query.Where(x => (int)x.Priority >= request.MinPriority.Value);
|
||||
}
|
||||
|
||||
var messages = await query
|
||||
.OrderByDescending(x => x.Priority)
|
||||
.ThenByDescending(x => x.Created)
|
||||
.Select(x => new PublicMessageDto
|
||||
{
|
||||
Id = x.Id,
|
||||
Title = x.Title,
|
||||
Content = x.Content,
|
||||
Type = x.Type,
|
||||
TypeName = GetTypeName(x.Type),
|
||||
Priority = x.Priority,
|
||||
PriorityName = GetPriorityName(x.Priority),
|
||||
StartsAt = x.StartsAt,
|
||||
ExpiresAt = x.ExpiresAt,
|
||||
LinkUrl = x.LinkUrl,
|
||||
LinkText = x.LinkText,
|
||||
Created = x.Created
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Retrieved {Count} active messages",
|
||||
messages.Count
|
||||
);
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
private static string GetTypeName(MessageType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
MessageType.Announcement => "اطلاعیه",
|
||||
MessageType.News => "اخبار",
|
||||
MessageType.Warning => "هشدار",
|
||||
MessageType.Promotion => "تبلیغات",
|
||||
MessageType.SystemUpdate => "بهروزرسانی سیستم",
|
||||
MessageType.Event => "رویداد",
|
||||
_ => "نامشخص"
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetPriorityName(MessagePriority priority)
|
||||
{
|
||||
return priority switch
|
||||
{
|
||||
MessagePriority.Low => "کم",
|
||||
MessagePriority.Medium => "متوسط",
|
||||
MessagePriority.High => "بالا",
|
||||
MessagePriority.Urgent => "فوری",
|
||||
_ => "نامشخص"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetActiveMessages;
|
||||
|
||||
/// <summary>
|
||||
/// DTO پیام عمومی برای نمایش به کاربران
|
||||
/// </summary>
|
||||
public class PublicMessageDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public MessageType Type { get; set; }
|
||||
public string TypeName { get; set; } = string.Empty;
|
||||
public MessagePriority Priority { get; set; }
|
||||
public string PriorityName { get; set; } = string.Empty;
|
||||
public DateTime StartsAt { get; set; }
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
public string? LinkUrl { get; set; }
|
||||
public string? LinkText { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetAllMessages;
|
||||
|
||||
/// <summary>
|
||||
/// DTO پیام عمومی برای Admin (با اطلاعات بیشتر)
|
||||
/// </summary>
|
||||
public class AdminPublicMessageDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public MessageType Type { get; set; }
|
||||
public string TypeName { get; set; } = string.Empty;
|
||||
public MessagePriority Priority { get; set; }
|
||||
public string PriorityName { get; set; } = string.Empty;
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime StartsAt { get; set; }
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
public long CreatedByUserId { get; set; }
|
||||
public int ViewCount { get; set; }
|
||||
public string? LinkUrl { get; set; }
|
||||
public string? LinkText { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
public DateTime? LastModified { get; set; }
|
||||
public bool IsExpired { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using MediatR;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetAllMessages;
|
||||
|
||||
/// <summary>
|
||||
/// کوئری دریافت همه پیامها (Admin)
|
||||
/// با فیلترها و صفحهبندی
|
||||
/// </summary>
|
||||
public class GetAllMessagesQuery : IRequest<GetAllMessagesResponseDto>
|
||||
{
|
||||
public int PageNumber { get; set; } = 1;
|
||||
public int PageSize { get; set; } = 10;
|
||||
|
||||
// فیلترها
|
||||
public bool? IsActive { get; set; }
|
||||
public MessageType? Type { get; set; }
|
||||
public MessagePriority? Priority { get; set; }
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public string? SearchTerm { get; set; }
|
||||
public bool OrderByDescending { get; set; } = true;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetAllMessages;
|
||||
|
||||
public class GetAllMessagesQueryHandler : IRequestHandler<GetAllMessagesQuery, GetAllMessagesResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ILogger<GetAllMessagesQueryHandler> _logger;
|
||||
|
||||
public GetAllMessagesQueryHandler(
|
||||
IApplicationDbContext context,
|
||||
ILogger<GetAllMessagesQueryHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<GetAllMessagesResponseDto> Handle(GetAllMessagesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
// Query پایه
|
||||
var query = _context.PublicMessages
|
||||
.Where(x => !x.IsDeleted);
|
||||
|
||||
// فیلترها
|
||||
if (request.IsActive.HasValue)
|
||||
{
|
||||
query = query.Where(x => x.IsActive == request.IsActive.Value);
|
||||
}
|
||||
|
||||
if (request.Type.HasValue)
|
||||
{
|
||||
query = query.Where(x => x.Type == request.Type.Value);
|
||||
}
|
||||
|
||||
if (request.Priority.HasValue)
|
||||
{
|
||||
query = query.Where(x => x.Priority == request.Priority.Value);
|
||||
}
|
||||
|
||||
if (request.StartDate.HasValue)
|
||||
{
|
||||
query = query.Where(x => x.Created >= request.StartDate.Value);
|
||||
}
|
||||
|
||||
if (request.EndDate.HasValue)
|
||||
{
|
||||
query = query.Where(x => x.Created <= request.EndDate.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.SearchTerm))
|
||||
{
|
||||
var searchTerm = request.SearchTerm.ToLower();
|
||||
query = query.Where(x => x.Title.ToLower().Contains(searchTerm)
|
||||
|| x.Content.ToLower().Contains(searchTerm));
|
||||
}
|
||||
|
||||
// تعداد کل
|
||||
var totalCount = await query.CountAsync(cancellationToken);
|
||||
|
||||
// مرتبسازی
|
||||
query = request.OrderByDescending
|
||||
? query.OrderByDescending(x => x.Created)
|
||||
: query.OrderBy(x => x.Created);
|
||||
|
||||
// صفحهبندی
|
||||
var messages = await query
|
||||
.Skip((request.PageNumber - 1) * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.Select(x => new AdminPublicMessageDto
|
||||
{
|
||||
Id = x.Id,
|
||||
Title = x.Title,
|
||||
Content = x.Content,
|
||||
Type = x.Type,
|
||||
TypeName = GetTypeName(x.Type),
|
||||
Priority = x.Priority,
|
||||
PriorityName = GetPriorityName(x.Priority),
|
||||
IsActive = x.IsActive,
|
||||
StartsAt = x.StartsAt,
|
||||
ExpiresAt = x.ExpiresAt,
|
||||
CreatedByUserId = x.CreatedByUserId,
|
||||
ViewCount = x.ViewCount,
|
||||
LinkUrl = x.LinkUrl,
|
||||
LinkText = x.LinkText,
|
||||
Created = x.Created,
|
||||
LastModified = x.LastModified,
|
||||
IsExpired = x.ExpiresAt < now
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var metaData = new MetaData
|
||||
{
|
||||
TotalCount = totalCount,
|
||||
PageSize = request.PageSize,
|
||||
CurrentPage = request.PageNumber,
|
||||
TotalPage = (int)Math.Ceiling(totalCount / (double)request.PageSize),
|
||||
HasNext = request.PageNumber < (int)Math.Ceiling(totalCount / (double)request.PageSize),
|
||||
HasPrevious = request.PageNumber > 1
|
||||
};
|
||||
|
||||
_logger.LogInformation(
|
||||
"Retrieved {Count} messages. Total: {Total}",
|
||||
messages.Count,
|
||||
totalCount
|
||||
);
|
||||
|
||||
return new GetAllMessagesResponseDto
|
||||
{
|
||||
MetaData = metaData,
|
||||
Messages = messages
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetTypeName(MessageType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
MessageType.Announcement => "اطلاعیه",
|
||||
MessageType.News => "اخبار",
|
||||
MessageType.Warning => "هشدار",
|
||||
MessageType.Promotion => "تبلیغات",
|
||||
MessageType.SystemUpdate => "بهروزرسانی سیستم",
|
||||
MessageType.Event => "رویداد",
|
||||
_ => "نامشخص"
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetPriorityName(MessagePriority priority)
|
||||
{
|
||||
return priority switch
|
||||
{
|
||||
MessagePriority.Low => "کم",
|
||||
MessagePriority.Medium => "متوسط",
|
||||
MessagePriority.High => "بالا",
|
||||
MessagePriority.Urgent => "فوری",
|
||||
_ => "نامشخص"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
using CMSMicroservice.Application.PublicMessageCQ.Queries.GetActiveMessages;
|
||||
|
||||
namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetAllMessages;
|
||||
|
||||
/// <summary>
|
||||
/// Response DTO برای لیست پیامها با متادیتا
|
||||
/// </summary>
|
||||
public class GetAllMessagesResponseDto
|
||||
{
|
||||
public MetaData MetaData { get; set; } = new();
|
||||
public List<AdminPublicMessageDto> Messages { get; set; } = new();
|
||||
}
|
||||
Reference in New Issue
Block a user