Files
emall-api/FutureMailAPI/Services/PersonalSpaceService.cs

419 lines
17 KiB
C#
Raw Normal View History

2025-10-16 09:56:36 +08:00
using Microsoft.EntityFrameworkCore;
using FutureMailAPI.Data;
using FutureMailAPI.Models;
using FutureMailAPI.DTOs;
using System.Text.Json;
namespace FutureMailAPI.Services
{
public class PersonalSpaceService : IPersonalSpaceService
{
private readonly FutureMailDbContext _context;
private readonly ILogger<PersonalSpaceService> _logger;
public PersonalSpaceService(FutureMailDbContext context, ILogger<PersonalSpaceService> logger)
{
_context = context;
_logger = logger;
}
public async Task<ApiResponse<TimelineResponseDto>> GetTimelineAsync(int userId, TimelineQueryDto query)
{
try
{
var response = new TimelineResponseDto();
var timelineDict = new Dictionary<string, TimelineDateDto>();
// 获取发送的邮件
if (query.Type == TimelineType.ALL || query.Type == TimelineType.SENT)
{
var sentMailsQuery = _context.SentMails
.Where(m => m.SenderId == userId)
.Include(m => m.Recipient)
.AsQueryable();
if (query.StartDate.HasValue)
{
sentMailsQuery = sentMailsQuery.Where(m => m.SentAt >= query.StartDate.Value);
}
if (query.EndDate.HasValue)
{
sentMailsQuery = sentMailsQuery.Where(m => m.SentAt <= query.EndDate.Value);
}
var sentMails = await sentMailsQuery
.OrderBy(m => m.SentAt)
.ToListAsync();
foreach (var mail in sentMails)
{
var dateKey = mail.SentAt.ToString("yyyy-MM-dd");
if (!timelineDict.ContainsKey(dateKey))
{
timelineDict[dateKey] = new TimelineDateDto
{
Date = dateKey,
Events = new List<TimelineEventDto>()
};
}
var recipientName = mail.Recipient?.Username ?? "自己";
var recipientAvatar = mail.Recipient?.Avatar;
timelineDict[dateKey].Events.Add(new TimelineEventDto
{
Type = TimelineEventType.SENT,
MailId = mail.Id,
Title = mail.Title,
Time = mail.SentAt.ToString("HH:mm"),
WithUser = new UserInfoDto
{
UserId = mail.RecipientId ?? 0,
Username = recipientName,
Avatar = recipientAvatar
},
Emotion = AnalyzeMailEmotion(mail.Content)
});
}
}
// 获取接收的邮件
if (query.Type == TimelineType.ALL || query.Type == TimelineType.RECEIVED)
{
var receivedMailsQuery = _context.ReceivedMails
.Where(r => r.RecipientId == userId)
.Include(r => r.SentMail)
.ThenInclude(m => m.Sender)
.AsQueryable();
if (query.StartDate.HasValue)
{
receivedMailsQuery = receivedMailsQuery.Where(r => r.ReceivedAt >= query.StartDate.Value);
}
if (query.EndDate.HasValue)
{
receivedMailsQuery = receivedMailsQuery.Where(r => r.ReceivedAt <= query.EndDate.Value);
}
var receivedMails = await receivedMailsQuery
.OrderBy(r => r.ReceivedAt)
.ToListAsync();
foreach (var receivedMail in receivedMails)
{
var dateKey = receivedMail.ReceivedAt.ToString("yyyy-MM-dd");
if (!timelineDict.ContainsKey(dateKey))
{
timelineDict[dateKey] = new TimelineDateDto
{
Date = dateKey,
Events = new List<TimelineEventDto>()
};
}
var senderName = receivedMail.SentMail.Sender.Username;
var senderAvatar = receivedMail.SentMail.Sender.Avatar;
timelineDict[dateKey].Events.Add(new TimelineEventDto
{
Type = TimelineEventType.RECEIVED,
MailId = receivedMail.SentMailId,
Title = receivedMail.SentMail.Title,
Time = receivedMail.ReceivedAt.ToString("HH:mm"),
WithUser = new UserInfoDto
{
UserId = receivedMail.SentMail.SenderId,
Username = senderName,
Avatar = senderAvatar
},
Emotion = AnalyzeMailEmotion(receivedMail.SentMail.Content)
});
}
}
// 对每个日期的事件按时间排序
foreach (var dateEntry in timelineDict)
{
dateEntry.Value.Events = dateEntry.Value.Events
.OrderBy(e => e.Time)
.ToList();
}
// 按日期排序
response.Timeline = timelineDict
.OrderBy(kvp => kvp.Key)
.Select(kvp => kvp.Value)
.ToList();
return ApiResponse<TimelineResponseDto>.SuccessResult(response);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取时间线时发生错误");
return ApiResponse<TimelineResponseDto>.ErrorResult("获取时间线失败");
}
}
public async Task<ApiResponse<StatisticsResponseDto>> GetStatisticsAsync(int userId)
{
try
{
var response = new StatisticsResponseDto();
// 获取发送的邮件统计
var sentMails = await _context.SentMails
.Where(m => m.SenderId == userId)
.ToListAsync();
response.TotalSent = sentMails.Count;
// 获取接收的邮件统计
var receivedMails = await _context.ReceivedMails
.Where(r => r.RecipientId == userId)
.Include(r => r.SentMail)
.ThenInclude(m => m.Sender)
.ToListAsync();
response.TotalReceived = receivedMails.Count;
// 计算时间旅行时长(天)
if (sentMails.Any())
{
var earliestDelivery = sentMails.Min(m => m.DeliveryTime);
var latestDelivery = sentMails.Max(m => m.DeliveryTime);
response.TimeTravelDuration = (latestDelivery - earliestDelivery).Days;
}
// 找出最频繁的收件人
var recipientCounts = sentMails
.Where(m => m.RecipientId.HasValue)
.GroupBy(m => m.RecipientId)
.Select(g => new { RecipientId = g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.FirstOrDefault();
if (recipientCounts != null)
{
var recipient = await _context.Users
.FirstOrDefaultAsync(u => u.Id == recipientCounts.RecipientId);
response.MostFrequentRecipient = recipient?.Username ?? "未知用户";
}
// 找出最常见的年份(投递年份)
if (sentMails.Any())
{
var yearCounts = sentMails
.GroupBy(m => m.DeliveryTime.Year)
.Select(g => new { Year = g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.FirstOrDefault();
response.MostCommonYear = yearCounts?.Year ?? DateTime.Now.Year;
}
// 生成关键词云
var allContents = sentMails.Select(m => m.Content).ToList();
allContents.AddRange(receivedMails.Select(r => r.SentMail.Content));
response.KeywordCloud = GenerateKeywordCloud(allContents);
// 生成月度统计
response.MonthlyStats = GenerateMonthlyStats(sentMails, receivedMails);
return ApiResponse<StatisticsResponseDto>.SuccessResult(response);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取统计数据时发生错误");
return ApiResponse<StatisticsResponseDto>.ErrorResult("获取统计数据失败");
}
}
public async Task<ApiResponse<SubscriptionResponseDto>> GetSubscriptionAsync(int userId)
{
try
{
// 在实际应用中,这里会从数据库或订阅服务中获取用户的订阅信息
// 目前我们使用模拟数据
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Id == userId);
if (user == null)
{
return ApiResponse<SubscriptionResponseDto>.ErrorResult("用户不存在");
}
// 模拟订阅数据
var response = new SubscriptionResponseDto
{
Plan = SubscriptionPlan.FREE, // 默认为免费计划
RemainingMails = 10 - await _context.SentMails.CountAsync(m => m.SenderId == userId && m.SentAt.Month == DateTime.Now.Month),
MaxAttachmentSize = 5 * 1024 * 1024, // 5MB
Features = new SubscriptionFeaturesDto
{
AdvancedTriggers = false,
CustomCapsules = false,
AIAssistant = true,
UnlimitedStorage = false,
PriorityDelivery = false
},
ExpireDate = null // 免费计划没有过期时间
};
// 如果用户创建时间超过30天可以升级为高级用户模拟
if (user.CreatedAt.AddDays(30) < DateTime.UtcNow)
{
response.Plan = SubscriptionPlan.PREMIUM;
response.RemainingMails = 100;
response.MaxAttachmentSize = 50 * 1024 * 1024; // 50MB
response.Features.AdvancedTriggers = true;
response.Features.CustomCapsules = true;
response.Features.UnlimitedStorage = true;
response.ExpireDate = DateTime.UtcNow.AddMonths(1);
}
return ApiResponse<SubscriptionResponseDto>.SuccessResult(response);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取订阅信息时发生错误");
return ApiResponse<SubscriptionResponseDto>.ErrorResult("获取订阅信息失败");
}
}
public async Task<ApiResponse<UserProfileResponseDto>> GetUserProfileAsync(int userId)
{
try
{
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Id == userId);
if (user == null)
{
return ApiResponse<UserProfileResponseDto>.ErrorResult("用户不存在");
}
// 获取订阅信息
var subscriptionResult = await GetSubscriptionAsync(userId);
var response = new UserProfileResponseDto
{
Id = user.Id,
Username = user.Username,
Email = user.Email,
Nickname = user.Nickname,
Avatar = user.Avatar,
CreatedAt = user.CreatedAt,
LastLoginAt = user.LastLoginAt,
Subscription = subscriptionResult.Data ?? new SubscriptionResponseDto()
};
return ApiResponse<UserProfileResponseDto>.SuccessResult(response);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取用户资料时发生错误");
return ApiResponse<UserProfileResponseDto>.ErrorResult("获取用户资料失败");
}
}
private string AnalyzeMailEmotion(string content)
{
// 简单的情感分析
var positiveKeywords = new[] { "开心", "快乐", "爱", "美好", "成功", "希望", "感谢", "幸福" };
var negativeKeywords = new[] { "悲伤", "难过", "失败", "痛苦", "失望", "愤怒", "焦虑", "恐惧" };
var positiveCount = positiveKeywords.Count(keyword => content.Contains(keyword));
var negativeCount = negativeKeywords.Count(keyword => content.Contains(keyword));
if (positiveCount > negativeCount)
return "积极";
else if (negativeCount > positiveCount)
return "消极";
else
return "中性";
}
private List<KeywordCloudDto> GenerateKeywordCloud(List<string> contents)
{
// 简单的关键词提取
var allWords = new List<string>();
foreach (var content in contents)
{
var words = content.Split(new[] { ' ', ',', '.', '!', '?', ';', ':', '', '。', '', '', '', '' }, StringSplitOptions.RemoveEmptyEntries);
allWords.AddRange(words.Where(word => word.Length > 3));
}
var wordCounts = allWords
.GroupBy(word => word)
.Select(g => new { Word = g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.Take(20)
.ToList();
var maxCount = wordCounts.FirstOrDefault()?.Count ?? 1;
return wordCounts.Select(w => new KeywordCloudDto
{
Word = w.Word,
Count = w.Count,
Size = (int)((double)w.Count / maxCount * 10) + 1 // 1-10的大小
}).ToList();
}
private List<MonthlyStatsDto> GenerateMonthlyStats(List<SentMail> sentMails, List<ReceivedMail> receivedMails)
{
var monthlyStats = new Dictionary<string, MonthlyStatsDto>();
// 处理发送的邮件
foreach (var mail in sentMails)
{
var monthKey = mail.SentAt.ToString("yyyy-MM");
if (!monthlyStats.ContainsKey(monthKey))
{
monthlyStats[monthKey] = new MonthlyStatsDto
{
Month = monthKey,
Sent = 0,
Received = 0
};
}
monthlyStats[monthKey].Sent++;
}
// 处理接收的邮件
foreach (var receivedMail in receivedMails)
{
var monthKey = receivedMail.ReceivedAt.ToString("yyyy-MM");
if (!monthlyStats.ContainsKey(monthKey))
{
monthlyStats[monthKey] = new MonthlyStatsDto
{
Month = monthKey,
Sent = 0,
Received = 0
};
}
monthlyStats[monthKey].Received++;
}
// 按月份排序只返回最近12个月的数据
return monthlyStats
.OrderBy(kvp => kvp.Key)
.TakeLast(12)
.Select(kvp => kvp.Value)
.ToList();
}
}
}