Spaces:
Runtime error
Runtime error
File size: 7,950 Bytes
3dd5c9a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | using Microsoft.EntityFrameworkCore;
using TaskTrackingSystem.Database.AppDbContextModels;
using TaskTrackingSystem.Shared;
using TaskTrackingSystem.Shared.Models.Notification;
using DbNotification = TaskTrackingSystem.Database.AppDbContextModels.Notification;
namespace TaskTrackingSystem.WebApi.Features.Notification;
public class NotificationService
{
private readonly AppDbContext _db;
private readonly NotificationRealtimeService _realtimeService;
public NotificationService(AppDbContext db, NotificationRealtimeService realtimeService)
{
_db = db;
_realtimeService = realtimeService;
}
public async Task<IReadOnlyList<NotificationDto>> GetRecentAsync(long userId, int take = 10)
{
var items = await (
from n in _db.Notifications
where n.RecipientId == userId
join sender in _db.Users on n.SenderId equals sender.Id into senderGroup
from sender in senderGroup.DefaultIfEmpty()
orderby n.CreatedAt descending
select new NotificationDto
{
Id = n.Id,
Title = n.Title,
TitleMy = n.TitleMy,
Body = n.Body,
BodyMy = n.BodyMy,
NotificationType = n.NotificationType,
SourceType = n.SourceType,
SourceId = n.SourceId,
IsRead = n.IsRead,
CreatedAt = n.CreatedAt,
ReadAt = n.ReadAt,
SenderName = sender == null ? null : $"{sender.FirstName} {sender.LastName}",
SenderNameMy = sender == null ? null : $"{sender.FirstNameMy} {sender.LastNameMy}"
})
.Take(take)
.ToListAsync();
await EnrichLocalizedTextAsync(items);
foreach (var item in items)
{
item.TargetUrl = NotificationNavigation.BuildTargetUrl(item.SourceType, item.SourceId, item.NotificationType);
}
return items;
}
private async global::System.Threading.Tasks.Task EnrichLocalizedTextAsync(List<NotificationDto> items)
{
if (items.Count == 0)
{
return;
}
var taskIds = items
.Where(item => item.SourceType.Equals("task", StringComparison.OrdinalIgnoreCase))
.Select(item => item.SourceId)
.Distinct()
.ToList();
var projectIds = items
.Where(item => item.SourceType.Equals("project", StringComparison.OrdinalIgnoreCase))
.Select(item => item.SourceId)
.Distinct()
.ToList();
var tasks = taskIds.Count == 0
? new Dictionary<long, (string Title, string? TitleMy)>()
: await _db.Tasks
.Where(task => taskIds.Contains(task.Id))
.Select(task => new { task.Id, task.Title, task.TitleMy })
.ToDictionaryAsync(task => task.Id, task => (task.Title, task.TitleMy));
var projects = projectIds.Count == 0
? new Dictionary<long, (string Name, string? NameMy)>()
: await _db.Projects
.Where(project => projectIds.Contains(project.Id))
.Select(project => new { project.Id, project.Name, project.NameMy })
.ToDictionaryAsync(project => project.Id, project => (project.Name, project.NameMy));
foreach (var item in items)
{
item.TitleMy = string.IsNullOrWhiteSpace(item.TitleMy)
? GetTitleMy((NotificationType)item.NotificationType)
: item.TitleMy;
if (!string.IsNullOrWhiteSpace(item.BodyMy))
{
continue;
}
if (item.SourceType.Equals("task", StringComparison.OrdinalIgnoreCase)
&& tasks.TryGetValue(item.SourceId, out var task))
{
var taskTitle = string.IsNullOrWhiteSpace(task.TitleMy) ? task.Title : task.TitleMy;
item.BodyMy = (NotificationType)item.NotificationType switch
{
NotificationType.TaskAssigned => $"သင့်အား လုပ်ငန်းသစ်တစ်ခု တာဝန်ပေးအပ်ထားပါသည် - {taskTitle}",
NotificationType.CommentAdded => $"{GetSenderNameMy(item)} သည် လုပ်ငန်း '{taskTitle}' တွင် မှတ်ချက်တစ်ခု ရေးသားခဲ့ပါသည်",
NotificationType.Mention => $"{GetSenderNameMy(item)} သည် လုပ်ငန်း '{taskTitle}' တွင် သင့်ကို ရည်ညွှန်းဖော်ပြခဲ့ပါသည်",
_ => item.BodyMy
};
}
if (item.SourceType.Equals("project", StringComparison.OrdinalIgnoreCase)
&& projects.TryGetValue(item.SourceId, out var project)
&& (NotificationType)item.NotificationType == NotificationType.ProjectUpdated)
{
var projectName = string.IsNullOrWhiteSpace(project.NameMy) ? project.Name : project.NameMy;
item.BodyMy = $"သင့်အား စီမံကိန်း '{projectName}' တွင် တာဝန်ပေးအပ်ထားပါသည်";
}
}
}
private static string? GetTitleMy(NotificationType notificationType) => notificationType switch
{
NotificationType.TaskAssigned => "လုပ်ငန်းတာဝန် ပေးအပ်ခြင်း",
NotificationType.StatusChanged => "လုပ်ငန်းအခြေအနေ ပြောင်းလဲခြင်း",
NotificationType.ProjectUpdated => "စီမံကိန်းတာဝန် ပေးအပ်ခြင်း",
NotificationType.CommentAdded => "မှတ်ချက်အသစ် ရေးသားခြင်း",
NotificationType.Mention => "သင့်ကို ရည်ညွှန်းဖော်ပြခြင်း",
_ => null
};
private static string GetSenderNameMy(NotificationDto item)
{
if (!string.IsNullOrWhiteSpace(item.SenderNameMy))
{
return item.SenderNameMy.Trim();
}
if (string.Equals(item.SenderName, "System Admin", StringComparison.OrdinalIgnoreCase))
{
return "စနစ်အုပ်ချုပ်သူ";
}
return string.IsNullOrWhiteSpace(item.SenderName) ? "စနစ်" : item.SenderName.Trim();
}
public async Task<int> GetUnreadCountAsync(long userId)
{
return await _db.Notifications.CountAsync(n => n.RecipientId == userId && !n.IsRead);
}
public async Task<Result> MarkReadAsync(long userId, long notificationId)
{
var notification = await _db.Notifications
.FirstOrDefaultAsync(n => n.Id == notificationId && n.RecipientId == userId);
if (notification == null)
{
return Result.Failure("Notification not found.", 404);
}
if (!notification.IsRead)
{
notification.IsRead = true;
notification.ReadAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
var unreadCount = await GetUnreadCountAsync(userId);
await _realtimeService.SendReadAsync(userId, notificationId, unreadCount);
}
return Result.Success();
}
public async Task<int> DeleteReadNotificationsAsync(long userId, DateTime? olderThanUtc = null)
{
var query = _db.Notifications.Where(n => n.RecipientId == userId && n.IsRead);
if (olderThanUtc.HasValue)
{
var cutoff = olderThanUtc.Value;
query = query.Where(n => !n.CreatedAt.HasValue || n.CreatedAt < cutoff);
}
return await query.ExecuteDeleteAsync();
}
}
|