209 lines
8.6 KiB
C#
209 lines
8.6 KiB
C#
using GozareshgirProgramManager.Application._Common.Interfaces;
|
|
using GozareshgirProgramManager.Application._Common.Models;
|
|
using GozareshgirProgramManager.Application.Modules.TaskChat.DTOs;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace GozareshgirProgramManager.Application.Modules.TaskChat.Queries.GetMessages;
|
|
|
|
public record GetMessagesQuery(
|
|
Guid TaskId,
|
|
int Page = 1,
|
|
int PageSize = 50
|
|
) : IBaseQuery<PaginationResult<MessageDto>>;
|
|
|
|
|
|
|
|
public class GetMessagesQueryHandler : IBaseQueryHandler<GetMessagesQuery, PaginationResult<MessageDto>>
|
|
{
|
|
private readonly IProgramManagerDbContext _context;
|
|
private readonly IAuthHelper _authHelper;
|
|
|
|
public GetMessagesQueryHandler(IProgramManagerDbContext context, IAuthHelper authHelper)
|
|
{
|
|
_context = context;
|
|
_authHelper = authHelper;
|
|
}
|
|
|
|
private List<MessageDto> CreateAdditionalTimeNotes(
|
|
IEnumerable<Domain.ProjectAgg.Entities.TaskSectionAdditionalTime> additionalTimes,
|
|
Dictionary<long, string> users,
|
|
Guid taskId)
|
|
{
|
|
var notes = new List<MessageDto>();
|
|
|
|
foreach (var additionalTime in additionalTimes)
|
|
{
|
|
var addedByUserName = additionalTime.AddedByUserId.HasValue && users.TryGetValue(additionalTime.AddedByUserId.Value, out var user)
|
|
? user
|
|
: "سیستم";
|
|
|
|
var noteContent = $"⏱️ زمان اضافی: {additionalTime.Hours.TotalHours.ToString("F2")} ساعت - {(string.IsNullOrWhiteSpace(additionalTime.Reason) ? "بدون علت" : additionalTime.Reason)} - توسط {addedByUserName}";
|
|
|
|
var noteDto = new MessageDto
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
TaskId = taskId,
|
|
SenderUserId = 0,
|
|
SenderName = "سیستم",
|
|
MessageType = "Note",
|
|
TextContent = noteContent,
|
|
CreationDate = additionalTime.CreationDate,
|
|
IsMine = false
|
|
};
|
|
|
|
notes.Add(noteDto);
|
|
}
|
|
|
|
return notes;
|
|
}
|
|
|
|
public async Task<OperationResult<PaginationResult<MessageDto>>> Handle(GetMessagesQuery request, CancellationToken cancellationToken)
|
|
{
|
|
var currentUserId = _authHelper.GetCurrentUserId();
|
|
|
|
var skip = (request.Page - 1) * request.PageSize;
|
|
|
|
var query = _context.TaskChatMessages
|
|
.Where(m => m.TaskId == request.TaskId && !m.IsDeleted)
|
|
.Include(m => m.ReplyToMessage)
|
|
.OrderBy(m => m.CreationDate);
|
|
|
|
var totalCount = await query.CountAsync(cancellationToken);
|
|
|
|
var messages = await query
|
|
.Skip(skip)
|
|
.Take(request.PageSize)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
// ✅ گرفتن تمامی کاربران برای نمایش نام کامل فرستنده به جای "کاربر"
|
|
var senderUserIds = messages.Select(m => m.SenderUserId).Distinct().ToList();
|
|
var users = await _context.Users
|
|
.Where(u => senderUserIds.Contains(u.Id))
|
|
.ToDictionaryAsync(u => u.Id, u => u.FullName, cancellationToken);
|
|
|
|
// ✅ گرفتن تمامی زمانهای اضافی (Additional Times) برای نمایش به صورت نوت
|
|
var taskSections = await _context.TaskSections
|
|
.Where(ts => ts.TaskId == request.TaskId)
|
|
.Include(ts => ts.AdditionalTimes)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
// ✅ تمام زمانهای اضافی را یکجا بگیر و مرتب کن
|
|
var allAdditionalTimes = taskSections
|
|
.SelectMany(ts => ts.AdditionalTimes)
|
|
.OrderBy(at => at.CreationDate)
|
|
.ToList();
|
|
|
|
var messageDtos = new List<MessageDto>();
|
|
|
|
// ✅ ابتدا زمانهای اضافی قبل از اولین پیام را اضافه کن (اگر پیامی وجود داشته باشد)
|
|
if (messages.Any())
|
|
{
|
|
var firstMessageDate = messages.First().CreationDate;
|
|
var additionalTimesBeforeFirstMessage = allAdditionalTimes
|
|
.Where(at => at.CreationDate < firstMessageDate)
|
|
.ToList();
|
|
|
|
messageDtos.AddRange(CreateAdditionalTimeNotes(additionalTimesBeforeFirstMessage, users, request.TaskId));
|
|
}
|
|
else
|
|
{
|
|
// ✅ اگر هیچ پیامی وجود ندارد، همه زمانهای اضافی را نمایش بده
|
|
messageDtos.AddRange(CreateAdditionalTimeNotes(allAdditionalTimes, users, request.TaskId));
|
|
}
|
|
|
|
foreach (var message in messages)
|
|
{
|
|
// ✅ نام فرستنده را از Dictionary Users بگیر، در صورت عدم وجود "کاربر ناشناس" نمایش بده
|
|
var senderName = users.GetValueOrDefault(message.SenderUserId, "کاربر ناشناس");
|
|
|
|
var dto = new MessageDto
|
|
{
|
|
Id = message.Id,
|
|
TaskId = message.TaskId,
|
|
SenderUserId = message.SenderUserId,
|
|
SenderName = senderName,
|
|
MessageType = message.MessageType.ToString(),
|
|
TextContent = message.TextContent,
|
|
ReplyToMessageId = message.ReplyToMessageId,
|
|
IsEdited = message.IsEdited,
|
|
EditedDate = message.EditedDate,
|
|
IsPinned = message.IsPinned,
|
|
PinnedDate = message.PinnedDate,
|
|
PinnedByUserId = message.PinnedByUserId,
|
|
CreationDate = message.CreationDate,
|
|
IsMine = message.SenderUserId == currentUserId
|
|
};
|
|
|
|
if (message.ReplyToMessage != null)
|
|
{
|
|
var replySenderName = users.GetValueOrDefault(message.ReplyToMessage.SenderUserId, "کاربر ناشناس");
|
|
|
|
dto.ReplyToMessage = new MessageDto
|
|
{
|
|
Id = message.ReplyToMessage.Id,
|
|
SenderUserId = message.ReplyToMessage.SenderUserId,
|
|
SenderName = replySenderName,
|
|
TextContent = message.ReplyToMessage.TextContent,
|
|
CreationDate = message.ReplyToMessage.CreationDate
|
|
};
|
|
}
|
|
|
|
if (message.FileId.HasValue)
|
|
{
|
|
var file = await _context.UploadedFiles.FirstOrDefaultAsync(f => f.Id == message.FileId.Value, cancellationToken);
|
|
if (file != null)
|
|
{
|
|
dto.File = new MessageFileDto
|
|
{
|
|
Id = file.Id,
|
|
FileName = file.OriginalFileName,
|
|
FileUrl = file.StorageUrl ?? "",
|
|
FileSizeBytes = file.FileSizeBytes,
|
|
FileType = file.FileType.ToString(),
|
|
ThumbnailUrl = file.ThumbnailUrl,
|
|
ImageWidth = file.ImageWidth,
|
|
ImageHeight = file.ImageHeight,
|
|
DurationSeconds = file.DurationSeconds
|
|
};
|
|
}
|
|
}
|
|
|
|
messageDtos.Add(dto);
|
|
|
|
// ✅ پیدا کردن پیام بعدی (اگر وجود داشته باشد)
|
|
var currentIndex = messages.IndexOf(message);
|
|
var nextMessage = currentIndex < messages.Count - 1 ? messages[currentIndex + 1] : null;
|
|
|
|
if (nextMessage != null)
|
|
{
|
|
// ✅ زمانهای اضافی بین این پیام و پیام بعدی
|
|
var additionalTimesBetween = allAdditionalTimes
|
|
.Where(at => at.CreationDate > message.CreationDate && at.CreationDate < nextMessage.CreationDate)
|
|
.ToList();
|
|
|
|
messageDtos.AddRange(CreateAdditionalTimeNotes(additionalTimesBetween, users, request.TaskId));
|
|
}
|
|
else
|
|
{
|
|
// ✅ این آخرین پیام است، زمانهای اضافی بعد از آن را اضافه کن
|
|
var additionalTimesAfterLastMessage = allAdditionalTimes
|
|
.Where(at => at.CreationDate > message.CreationDate)
|
|
.ToList();
|
|
|
|
messageDtos.AddRange(CreateAdditionalTimeNotes(additionalTimesAfterLastMessage, users, request.TaskId));
|
|
}
|
|
}
|
|
|
|
// ✅ مرتب کردن نهایی تمام پیامها (معمولی + نوتها) بر اساس زمان ایجاد
|
|
messageDtos = messageDtos.OrderBy(m => m.CreationDate).ToList();
|
|
|
|
var response = new PaginationResult<MessageDto>()
|
|
{
|
|
List = messageDtos,
|
|
TotalCount = totalCount,
|
|
};
|
|
|
|
return OperationResult<PaginationResult<MessageDto>>.Success(response);
|
|
}
|
|
}
|