419 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			419 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								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();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |