173 lines
5.9 KiB
C#
173 lines
5.9 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using MilliSim.Common.Dtos;
|
|
using MilliSim.Common.Entities;
|
|
using MilliSim.Common.Models;
|
|
using MilliSim.Data;
|
|
using MilliSim.Services.Infrastructure;
|
|
|
|
namespace MilliSim.Services;
|
|
|
|
public class NotificationService : INotificationService
|
|
{
|
|
private readonly MilliSimDbContext _db;
|
|
private readonly ICurrentUserService _currentUser;
|
|
|
|
public NotificationService(MilliSimDbContext db, ICurrentUserService currentUser)
|
|
{
|
|
_db = db;
|
|
_currentUser = currentUser;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将通知类型枚举转为中文名称
|
|
/// </summary>
|
|
private static string GetTypeName(NotificationType type) => type switch
|
|
{
|
|
NotificationType.System => "系统",
|
|
NotificationType.Project => "项目",
|
|
NotificationType.Account => "账号",
|
|
NotificationType.Authorization => "授权",
|
|
_ => "通知"
|
|
};
|
|
|
|
public async Task<ApiResponse<PagedResult<NotificationDto>>> GetNotificationsAsync(NotificationType? type, PageRequest request)
|
|
{
|
|
var userId = _currentUser.UserId;
|
|
var query = _db.Notifications
|
|
.Where(n => n.UserId == null || n.UserId == userId);
|
|
|
|
if (type.HasValue)
|
|
query = query.Where(n => n.Type == type.Value);
|
|
|
|
if (!string.IsNullOrEmpty(request.Keyword))
|
|
query = query.Where(n => n.Title.Contains(request.Keyword) || n.Content.Contains(request.Keyword));
|
|
|
|
var total = await query.CountAsync();
|
|
var items = await query
|
|
.OrderByDescending(n => n.CreatedAt)
|
|
.Skip((request.PageIndex - 1) * request.PageSize)
|
|
.Take(request.PageSize)
|
|
.Select(n => new NotificationDto
|
|
{
|
|
Id = n.Id,
|
|
Type = n.Type,
|
|
Title = n.Title,
|
|
Content = n.Content,
|
|
IsRead = _db.NotificationReads.Any(r => r.NotificationId == n.Id && r.UserId == userId),
|
|
CreatedAt = n.CreatedAt
|
|
})
|
|
.ToListAsync();
|
|
|
|
// 在内存中设置中文类型名(避免 EF 翻译 switch 表达式)
|
|
foreach (var item in items)
|
|
item.TypeName = GetTypeName(item.Type);
|
|
|
|
return ApiResponse<PagedResult<NotificationDto>>.Success(
|
|
PagedResult<NotificationDto>.Create(items, total, request.PageIndex, request.PageSize));
|
|
}
|
|
|
|
public async Task<ApiResponse<int>> GetUnreadCountAsync()
|
|
{
|
|
var userId = _currentUser.UserId;
|
|
var count = await _db.Notifications
|
|
.Where(n => n.UserId == null || n.UserId == userId)
|
|
.Where(n => !_db.NotificationReads.Any(r => r.NotificationId == n.Id && r.UserId == userId))
|
|
.CountAsync();
|
|
|
|
return ApiResponse<int>.Success(count);
|
|
}
|
|
|
|
public async Task<ApiResponse> MarkAsReadAsync(long id)
|
|
{
|
|
var userId = _currentUser.UserId;
|
|
var notification = await _db.Notifications
|
|
.FirstOrDefaultAsync(n => n.Id == id && (n.UserId == null || n.UserId == userId));
|
|
if (notification == null)
|
|
return ApiResponse.Fail("通知不存在", 404);
|
|
|
|
var exists = await _db.NotificationReads
|
|
.AnyAsync(r => r.NotificationId == id && r.UserId == userId);
|
|
if (!exists)
|
|
{
|
|
_db.NotificationReads.Add(new NotificationRead
|
|
{
|
|
UserId = userId,
|
|
NotificationId = id
|
|
});
|
|
await _db.SaveChangesAsync();
|
|
}
|
|
|
|
return ApiResponse.Success("已标记为已读");
|
|
}
|
|
|
|
public async Task<ApiResponse> MarkAllAsReadAsync()
|
|
{
|
|
var userId = _currentUser.UserId;
|
|
var unreadIds = await _db.Notifications
|
|
.Where(n => n.UserId == null || n.UserId == userId)
|
|
.Where(n => !_db.NotificationReads.Any(r => r.NotificationId == n.Id && r.UserId == userId))
|
|
.Select(n => n.Id)
|
|
.ToListAsync();
|
|
|
|
foreach (var nid in unreadIds)
|
|
{
|
|
_db.NotificationReads.Add(new NotificationRead
|
|
{
|
|
UserId = userId,
|
|
NotificationId = nid
|
|
});
|
|
}
|
|
|
|
await _db.SaveChangesAsync();
|
|
return ApiResponse.Success($"已将 {unreadIds.Count} 条通知标记为已读");
|
|
}
|
|
|
|
public async Task<ApiResponse> DeleteNotificationAsync(long id)
|
|
{
|
|
var userId = _currentUser.UserId;
|
|
var notification = await _db.Notifications
|
|
.FirstOrDefaultAsync(n => n.Id == id && (n.UserId == null || n.UserId == userId));
|
|
if (notification == null)
|
|
return ApiResponse.Fail("通知不存在", 404);
|
|
|
|
notification.IsDeleted = true;
|
|
notification.UpdatedAt = DateTime.Now;
|
|
await _db.SaveChangesAsync();
|
|
|
|
return ApiResponse.Success("通知已删除");
|
|
}
|
|
|
|
public async Task<ApiResponse<NotificationDto>> CreateNotificationAsync(NotificationType type, string title, string content, long? userId = null, string? eventId = null)
|
|
{
|
|
// 根据 eventId 防重复
|
|
if (!string.IsNullOrEmpty(eventId))
|
|
{
|
|
var exists = await _db.Notifications.AnyAsync(n => n.EventId == eventId);
|
|
if (exists)
|
|
return ApiResponse<NotificationDto>.Fail("通知已存在", 409);
|
|
}
|
|
|
|
var notification = new Notification
|
|
{
|
|
Type = type,
|
|
Title = title,
|
|
Content = content,
|
|
UserId = userId,
|
|
EventId = eventId
|
|
};
|
|
_db.Notifications.Add(notification);
|
|
await _db.SaveChangesAsync();
|
|
|
|
return ApiResponse<NotificationDto>.Success(new NotificationDto
|
|
{
|
|
Id = notification.Id,
|
|
Type = notification.Type,
|
|
TypeName = GetTypeName(notification.Type),
|
|
Title = notification.Title,
|
|
Content = notification.Content,
|
|
IsRead = false,
|
|
CreatedAt = notification.CreatedAt
|
|
});
|
|
}
|
|
}
|