Files
emall-api/FutureMailAPI/Services/MailService.cs
2025-10-18 16:18:20 +08:00

928 lines
36 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.EntityFrameworkCore;
using FutureMailAPI.Data;
using FutureMailAPI.Models;
using FutureMailAPI.DTOs;
using System.Text.Json;
namespace FutureMailAPI.Services
{
public class MailService : IMailService
{
private readonly FutureMailDbContext _context;
public MailService(FutureMailDbContext context)
{
_context = context;
}
public async Task<ApiResponse<SentMailResponseDto>> CreateMailAsync(int userId, SentMailCreateDto createDto)
{
// 检查投递时间是否在未来
if (createDto.DeliveryTime <= DateTime.UtcNow)
{
return ApiResponse<SentMailResponseDto>.ErrorResult("投递时间必须是未来时间");
}
// 如果是指定用户,检查用户是否存在
int? recipientId = null;
if (createDto.RecipientType == 1 && !string.IsNullOrEmpty(createDto.RecipientEmail))
{
var recipient = await _context.Users
.FirstOrDefaultAsync(u => u.Email == createDto.RecipientEmail);
if (recipient == null)
{
return ApiResponse<SentMailResponseDto>.ErrorResult("收件人不存在");
}
recipientId = recipient.Id;
}
// 创建邮件
var mail = new SentMail
{
Title = createDto.Title,
Content = createDto.Content,
SenderId = userId,
RecipientType = createDto.RecipientType,
RecipientId = recipientId,
DeliveryTime = createDto.DeliveryTime,
SentAt = DateTime.UtcNow, // 显式设置发送时间
Status = createDto.DeliveryTime > DateTime.UtcNow ? 1 : 0, // 根据投递时间直接设置状态
TriggerType = createDto.TriggerType,
TriggerDetails = createDto.TriggerDetails,
Attachments = createDto.Attachments,
IsEncrypted = createDto.IsEncrypted,
EncryptionKey = createDto.EncryptionKey,
Theme = createDto.Theme
};
_context.SentMails.Add(mail);
await _context.SaveChangesAsync();
// 如果是发送状态(不是草稿),创建时间胶囊
if (mail.Status == 1) // 已发送(待投递)
{
// 创建时间胶囊
var timeCapsule = new TimeCapsule
{
UserId = userId,
SentMailId = mail.Id,
PositionX = 0,
PositionY = 0,
PositionZ = 0,
Status = 1, // 漂浮中
Type = 0 // 普通
};
_context.TimeCapsules.Add(timeCapsule);
await _context.SaveChangesAsync();
}
var mailResponse = await GetSentMailWithDetailsAsync(mail.Id);
return ApiResponse<SentMailResponseDto>.SuccessResult(mailResponse, "邮件创建成功");
}
public async Task<ApiResponse<PagedResponse<SentMailResponseDto>>> GetSentMailsAsync(int userId, MailListQueryDto queryDto)
{
var query = _context.SentMails
.Where(m => m.SenderId == userId)
.Include(m => m.Sender)
.Include(m => m.Recipient)
.AsQueryable();
// 应用筛选条件
if (queryDto.Status.HasValue)
{
query = query.Where(m => m.Status == queryDto.Status.Value);
}
if (queryDto.RecipientType.HasValue)
{
query = query.Where(m => m.RecipientType == queryDto.RecipientType.Value);
}
if (!string.IsNullOrEmpty(queryDto.Keyword))
{
query = query.Where(m => m.Title.Contains(queryDto.Keyword) || m.Content.Contains(queryDto.Keyword));
}
if (queryDto.StartDate.HasValue)
{
query = query.Where(m => m.SentAt >= queryDto.StartDate.Value);
}
if (queryDto.EndDate.HasValue)
{
query = query.Where(m => m.SentAt <= queryDto.EndDate.Value);
}
// 排序
query = query.OrderByDescending(m => m.SentAt);
// 分页
var totalCount = await query.CountAsync();
var mails = await query
.Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
.Take(queryDto.PageSize)
.ToListAsync();
var mailDtos = mails.Select(MapToSentMailResponseDto).ToList();
var pagedResponse = new PagedResponse<SentMailResponseDto>(
mailDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
return ApiResponse<PagedResponse<SentMailResponseDto>>.SuccessResult(pagedResponse);
}
public async Task<ApiResponse<SentMailResponseDto>> GetSentMailByIdAsync(int userId, int mailId)
{
var mail = await _context.SentMails
.Include(m => m.Sender)
.Include(m => m.Recipient)
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<SentMailResponseDto>.ErrorResult("邮件不存在");
}
var mailDto = MapToSentMailResponseDto(mail);
return ApiResponse<SentMailResponseDto>.SuccessResult(mailDto);
}
public async Task<ApiResponse<SentMailResponseDto>> UpdateMailAsync(int userId, int mailId, SentMailUpdateDto updateDto)
{
var mail = await _context.SentMails
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<SentMailResponseDto>.ErrorResult("邮件不存在");
}
// 检查邮件是否已投递,已投递的邮件不能修改
if (mail.Status >= 2)
{
return ApiResponse<SentMailResponseDto>.ErrorResult("已投递的邮件不能修改");
}
// 更新邮件信息
if (updateDto.Title != null)
{
mail.Title = updateDto.Title;
}
if (updateDto.Content != null)
{
mail.Content = updateDto.Content;
}
if (updateDto.DeliveryTime.HasValue)
{
if (updateDto.DeliveryTime.Value <= DateTime.UtcNow)
{
return ApiResponse<SentMailResponseDto>.ErrorResult("投递时间必须是未来时间");
}
mail.DeliveryTime = updateDto.DeliveryTime.Value;
}
if (updateDto.TriggerDetails != null)
{
mail.TriggerDetails = updateDto.TriggerDetails;
}
if (updateDto.Attachments != null)
{
mail.Attachments = updateDto.Attachments;
}
if (updateDto.Theme != null)
{
mail.Theme = updateDto.Theme;
}
await _context.SaveChangesAsync();
var mailResponse = await GetSentMailWithDetailsAsync(mail.Id);
return ApiResponse<SentMailResponseDto>.SuccessResult(mailResponse, "邮件更新成功");
}
public async Task<ApiResponse<bool>> DeleteMailAsync(int userId, int mailId)
{
var mail = await _context.SentMails
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<bool>.ErrorResult("邮件不存在");
}
// 检查邮件是否已投递,已投递的邮件不能删除
if (mail.Status >= 2)
{
return ApiResponse<bool>.ErrorResult("已投递的邮件不能删除");
}
// 删除相关的时间胶囊
var timeCapsule = await _context.TimeCapsules
.FirstOrDefaultAsync(tc => tc.SentMailId == mailId);
if (timeCapsule != null)
{
_context.TimeCapsules.Remove(timeCapsule);
}
// 删除邮件
_context.SentMails.Remove(mail);
await _context.SaveChangesAsync();
return ApiResponse<bool>.SuccessResult(true, "邮件删除成功");
}
public async Task<ApiResponse<PagedResponse<ReceivedMailResponseDto>>> GetReceivedMailsAsync(int userId, MailListQueryDto queryDto)
{
var query = _context.ReceivedMails
.Where(r => r.RecipientId == userId)
.Include(r => r.SentMail)
.ThenInclude(m => m.Sender)
.AsQueryable();
// 应用筛选条件
if (queryDto.Status.HasValue)
{
if (queryDto.Status.Value == 0) // 未读
{
query = query.Where(r => !r.IsRead);
}
else if (queryDto.Status.Value == 1) // 已读
{
query = query.Where(r => r.IsRead);
}
}
if (!string.IsNullOrEmpty(queryDto.Keyword))
{
query = query.Where(r => r.SentMail.Title.Contains(queryDto.Keyword) || r.SentMail.Content.Contains(queryDto.Keyword));
}
if (queryDto.StartDate.HasValue)
{
query = query.Where(r => r.ReceivedAt >= queryDto.StartDate.Value);
}
if (queryDto.EndDate.HasValue)
{
query = query.Where(r => r.ReceivedAt <= queryDto.EndDate.Value);
}
// 排序
query = query.OrderByDescending(r => r.ReceivedAt);
// 分页
var totalCount = await query.CountAsync();
var receivedMails = await query
.Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
.Take(queryDto.PageSize)
.ToListAsync();
var mailDtos = receivedMails.Select(MapToReceivedMailResponseDto).ToList();
var pagedResponse = new PagedResponse<ReceivedMailResponseDto>(
mailDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
return ApiResponse<PagedResponse<ReceivedMailResponseDto>>.SuccessResult(pagedResponse);
}
public async Task<ApiResponse<ReceivedMailResponseDto>> GetReceivedMailByIdAsync(int userId, int mailId)
{
var receivedMail = await _context.ReceivedMails
.Include(r => r.SentMail)
.ThenInclude(m => m.Sender)
.FirstOrDefaultAsync(r => r.Id == mailId && r.RecipientId == userId);
if (receivedMail == null)
{
return ApiResponse<ReceivedMailResponseDto>.ErrorResult("邮件不存在");
}
var mailDto = MapToReceivedMailResponseDto(receivedMail);
return ApiResponse<ReceivedMailResponseDto>.SuccessResult(mailDto);
}
public async Task<ApiResponse<bool>> MarkReceivedMailAsReadAsync(int userId, int mailId)
{
var receivedMail = await _context.ReceivedMails
.FirstOrDefaultAsync(r => r.Id == mailId && r.RecipientId == userId);
if (receivedMail == null)
{
return ApiResponse<bool>.ErrorResult("邮件不存在");
}
if (!receivedMail.IsRead)
{
receivedMail.IsRead = true;
receivedMail.ReadAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
}
return ApiResponse<bool>.SuccessResult(true, "邮件已标记为已读");
}
public Task<ApiResponse<SentMailResponseDto>> GetMailByIdAsync(int userId, int mailId)
{
return GetSentMailByIdAsync(userId, mailId);
}
public Task<ApiResponse<PagedResponse<SentMailResponseDto>>> GetMailsAsync(int userId, MailListQueryDto queryDto)
{
return GetSentMailsAsync(userId, queryDto);
}
public Task<ApiResponse<bool>> MarkAsReadAsync(int userId, int mailId)
{
return MarkReceivedMailAsReadAsync(userId, mailId);
}
public async Task<ApiResponse<bool>> RevokeMailAsync(int userId, int mailId)
{
var mail = await _context.SentMails
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<bool>.ErrorResult("邮件不存在");
}
// 检查邮件是否已投递,已投递的邮件不能撤销
if (mail.Status >= 2)
{
return ApiResponse<bool>.ErrorResult("已投递的邮件不能撤销");
}
// 更新邮件状态为已撤销
mail.Status = 4; // 4-已撤销
await _context.SaveChangesAsync();
// 更新相关的时间胶囊状态
var timeCapsule = await _context.TimeCapsules
.FirstOrDefaultAsync(tc => tc.SentMailId == mailId);
if (timeCapsule != null)
{
timeCapsule.Status = 3; // 3-已撤销
await _context.SaveChangesAsync();
}
return ApiResponse<bool>.SuccessResult(true, "邮件已撤销");
}
// 存入胶囊相关方法实现
public async Task<ApiResponse<SaveToCapsuleResponseDto>> SaveToCapsuleAsync(int userId, SaveToCapsuleDto saveToCapsuleDto)
{
// 验证收件人类型
if (saveToCapsuleDto.RecipientType == RecipientTypeEnum.SPECIFIC && string.IsNullOrEmpty(saveToCapsuleDto.RecipientEmail))
{
return ApiResponse<SaveToCapsuleResponseDto>.ErrorResult("指定收件人时,收件人邮箱是必填项");
}
// 验证发送时间
if (saveToCapsuleDto.SendTime.HasValue && saveToCapsuleDto.SendTime.Value <= DateTime.UtcNow)
{
return ApiResponse<SaveToCapsuleResponseDto>.ErrorResult("发送时间必须是未来时间");
}
// 创建邮件
var mail = new SentMail
{
Title = saveToCapsuleDto.Title,
Content = saveToCapsuleDto.Content,
SenderId = userId,
RecipientType = (int)saveToCapsuleDto.RecipientType,
SentAt = DateTime.UtcNow,
CreatedAt = DateTime.UtcNow,
DeliveryTime = saveToCapsuleDto.SendTime ?? DateTime.UtcNow.AddDays(1), // 默认一天后发送
Status = 0, // 草稿状态
TriggerType = (int)saveToCapsuleDto.TriggerType,
TriggerDetails = saveToCapsuleDto.TriggerCondition != null ? JsonSerializer.Serialize(saveToCapsuleDto.TriggerCondition) : null,
Attachments = saveToCapsuleDto.Attachments != null ? JsonSerializer.Serialize(saveToCapsuleDto.Attachments) : null,
IsEncrypted = saveToCapsuleDto.IsEncrypted,
Theme = saveToCapsuleDto.CapsuleStyle
};
// 如果是指定收件人查找收件人ID
if (saveToCapsuleDto.RecipientType == RecipientTypeEnum.SPECIFIC && !string.IsNullOrEmpty(saveToCapsuleDto.RecipientEmail))
{
var recipient = await _context.Users
.FirstOrDefaultAsync(u => u.Email == saveToCapsuleDto.RecipientEmail);
if (recipient == null)
{
return ApiResponse<SaveToCapsuleResponseDto>.ErrorResult("收件人不存在");
}
mail.RecipientId = recipient.Id;
}
_context.SentMails.Add(mail);
await _context.SaveChangesAsync();
// 创建时间胶囊
var timeCapsule = new TimeCapsule
{
UserId = userId,
SentMailId = mail.Id,
Status = 0, // 草稿状态
CreatedAt = DateTime.UtcNow,
PositionX = 0.5f, // 默认位置
PositionY = 0.5f,
PositionZ = 0.5f,
Style = saveToCapsuleDto.CapsuleStyle,
GlowIntensity = 0.8f // 默认发光强度
};
_context.TimeCapsules.Add(timeCapsule);
await _context.SaveChangesAsync();
var response = new SaveToCapsuleResponseDto
{
Id = mail.Id,
MailId = mail.Id.ToString(),
CapsuleId = timeCapsule.Id.ToString(),
Status = "DRAFT",
CreatedAt = mail.CreatedAt
};
return ApiResponse<SaveToCapsuleResponseDto>.SuccessResult(response, "邮件已存入胶囊");
}
public async Task<ApiResponse<PagedResponse<CapsuleMailListResponseDto>>> GetCapsuleMailsAsync(int userId, MailListQueryDto queryDto)
{
var query = _context.SentMails
.Where(m => m.SenderId == userId && m.Status == 0) // 只查询草稿状态的邮件
.Include(m => m.Sender)
.Include(m => m.Recipient)
.Include(m => m.TimeCapsule)
.AsQueryable();
// 应用筛选条件
if (queryDto.Status.HasValue)
{
query = query.Where(m => m.Status == queryDto.Status.Value);
}
if (queryDto.RecipientType.HasValue)
{
query = query.Where(m => m.RecipientType == queryDto.RecipientType.Value);
}
if (!string.IsNullOrEmpty(queryDto.Keyword))
{
query = query.Where(m => m.Title.Contains(queryDto.Keyword) || m.Content.Contains(queryDto.Keyword));
}
if (queryDto.StartDate.HasValue)
{
query = query.Where(m => m.SentAt >= queryDto.StartDate.Value);
}
if (queryDto.EndDate.HasValue)
{
query = query.Where(m => m.SentAt <= queryDto.EndDate.Value);
}
// 排序
query = query.OrderByDescending(m => m.SentAt);
// 分页
var totalCount = await query.CountAsync();
var mails = await query
.Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
.Take(queryDto.PageSize)
.ToListAsync();
var mailDtos = mails.Select(MapToCapsuleMailListResponseDto).ToList();
var pagedResponse = new PagedResponse<CapsuleMailListResponseDto>(
mailDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
return ApiResponse<PagedResponse<CapsuleMailListResponseDto>>.SuccessResult(pagedResponse);
}
public async Task<ApiResponse<CapsuleMailDetailResponseDto>> GetCapsuleMailByIdAsync(int userId, int mailId)
{
var mail = await _context.SentMails
.Include(m => m.Sender)
.Include(m => m.Recipient)
.Include(m => m.TimeCapsule)
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("邮件不存在");
}
var mailDto = MapToCapsuleMailDetailResponseDto(mail);
return ApiResponse<CapsuleMailDetailResponseDto>.SuccessResult(mailDto);
}
public async Task<ApiResponse<CapsuleMailDetailResponseDto>> UpdateCapsuleMailAsync(int userId, int mailId, UpdateCapsuleMailDto updateDto)
{
var mail = await _context.SentMails
.Include(m => m.Sender)
.Include(m => m.Recipient)
.Include(m => m.TimeCapsule)
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("邮件不存在");
}
// 检查邮件状态,只有草稿状态的邮件才能编辑
if (mail.Status != 0)
{
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("只有草稿状态的邮件才能编辑");
}
// 更新邮件信息
if (!string.IsNullOrEmpty(updateDto.Title))
{
mail.Title = updateDto.Title;
}
if (!string.IsNullOrEmpty(updateDto.Content))
{
mail.Content = updateDto.Content;
}
if (updateDto.RecipientType.HasValue)
{
mail.RecipientType = (int)updateDto.RecipientType.Value;
// 如果是指定收件人查找收件人ID
if (updateDto.RecipientType.Value == RecipientTypeEnum.SPECIFIC && !string.IsNullOrEmpty(updateDto.RecipientEmail))
{
var recipient = await _context.Users
.FirstOrDefaultAsync(u => u.Email == updateDto.RecipientEmail);
if (recipient == null)
{
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("收件人不存在");
}
mail.RecipientId = recipient.Id;
}
}
if (updateDto.SendTime.HasValue)
{
if (updateDto.SendTime.Value <= DateTime.UtcNow)
{
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("发送时间必须是未来时间");
}
mail.DeliveryTime = updateDto.SendTime.Value;
}
if (updateDto.TriggerType.HasValue)
{
mail.TriggerType = (int)updateDto.TriggerType.Value;
}
if (updateDto.TriggerCondition != null)
{
mail.TriggerDetails = JsonSerializer.Serialize(updateDto.TriggerCondition);
}
if (updateDto.Attachments != null)
{
mail.Attachments = JsonSerializer.Serialize(updateDto.Attachments);
}
if (updateDto.IsEncrypted.HasValue)
{
mail.IsEncrypted = updateDto.IsEncrypted.Value;
}
if (!string.IsNullOrEmpty(updateDto.CapsuleStyle))
{
mail.Theme = updateDto.CapsuleStyle;
// 更新时间胶囊样式
if (mail.TimeCapsule != null)
{
mail.TimeCapsule.Style = updateDto.CapsuleStyle;
}
}
await _context.SaveChangesAsync();
var mailResponse = MapToCapsuleMailDetailResponseDto(mail);
return ApiResponse<CapsuleMailDetailResponseDto>.SuccessResult(mailResponse, "胶囊邮件更新成功");
}
public async Task<ApiResponse<bool>> RevokeCapsuleMailAsync(int userId, int mailId)
{
var mail = await _context.SentMails
.Include(m => m.TimeCapsule)
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<bool>.ErrorResult("邮件不存在");
}
// 检查邮件状态,只有草稿或待投递状态的邮件才能撤销
if (mail.Status > 1)
{
return ApiResponse<bool>.ErrorResult("已投递的邮件不能撤销");
}
// 更新邮件状态为已撤销
mail.Status = 4; // 4-已撤销
await _context.SaveChangesAsync();
// 更新相关的时间胶囊状态
if (mail.TimeCapsule != null)
{
mail.TimeCapsule.Status = 3; // 3-已撤销
await _context.SaveChangesAsync();
}
return ApiResponse<bool>.SuccessResult(true, "胶囊邮件已撤销");
}
private static CapsuleMailListResponseDto MapToCapsuleMailListResponseDto(SentMail mail)
{
return new CapsuleMailListResponseDto
{
MailId = mail.Id.ToString(),
Title = mail.Title,
Sender = MapToUserInfoDto(mail.Sender),
Recipient = mail.Recipient != null ? MapToUserInfoDto(mail.Recipient) : new UserInfoDto(),
SendTime = mail.SentAt,
DeliveryTime = mail.DeliveryTime,
Status = mail.Status switch
{
0 => "DRAFT",
1 => "PENDING",
2 => "DELIVERING",
3 => "DELIVERED",
_ => "UNKNOWN"
},
HasAttachments = !string.IsNullOrEmpty(mail.Attachments),
IsEncrypted = mail.IsEncrypted,
CapsuleStyle = mail.Theme ?? "default",
Countdown = mail.Status == 1 ? (int)(mail.DeliveryTime - DateTime.UtcNow).TotalSeconds : null
};
}
private static CapsuleMailDetailResponseDto MapToCapsuleMailDetailResponseDto(SentMail mail)
{
List<AttachmentDto> attachments = new List<AttachmentDto>();
if (!string.IsNullOrEmpty(mail.Attachments))
{
try
{
var attachmentList = JsonSerializer.Deserialize<List<object>>(mail.Attachments);
if (attachmentList != null)
{
attachments = attachmentList.Select(a => new AttachmentDto
{
Id = Guid.NewGuid().ToString(),
Type = "IMAGE", // 默认类型,实际应根据数据解析
Url = a.ToString() ?? "",
Size = 0 // 默认大小,实际应根据数据解析
}).ToList();
}
}
catch
{
// 解析失败时忽略附件
}
}
object? triggerCondition = null;
if (!string.IsNullOrEmpty(mail.TriggerDetails))
{
try
{
triggerCondition = JsonSerializer.Deserialize<object>(mail.TriggerDetails);
}
catch
{
// 解析失败时忽略触发条件
}
}
return new CapsuleMailDetailResponseDto
{
MailId = mail.Id.ToString(),
Title = mail.Title,
Content = mail.Content,
Sender = MapToUserInfoDto(mail.Sender),
Recipient = mail.Recipient != null ? MapToUserInfoDto(mail.Recipient) : new UserInfoDto(),
SendTime = mail.SentAt,
CreatedAt = mail.CreatedAt,
DeliveryTime = mail.DeliveryTime,
Status = mail.Status switch
{
0 => "DRAFT",
1 => "PENDING",
2 => "DELIVERING",
3 => "DELIVERED",
_ => "UNKNOWN"
},
TriggerType = mail.TriggerType switch
{
0 => "TIME",
1 => "LOCATION",
2 => "EVENT",
_ => "UNKNOWN"
},
TriggerCondition = triggerCondition,
Attachments = attachments,
IsEncrypted = mail.IsEncrypted,
CapsuleStyle = mail.Theme ?? "default",
CanEdit = mail.Status == 0, // 只有草稿状态可编辑
CanRevoke = mail.Status <= 1 // 草稿或待投递状态可撤销
};
}
private static UserInfoDto MapToUserInfoDto(User user)
{
return new UserInfoDto
{
UserId = user.Id,
Username = user.Username,
Avatar = user.Avatar ?? "",
Email = user.Email
};
}
private async Task<SentMailResponseDto> GetSentMailWithDetailsAsync(int mailId)
{
var mail = await _context.SentMails
.Include(m => m.Sender)
.Include(m => m.Recipient)
.FirstOrDefaultAsync(m => m.Id == mailId);
return MapToSentMailResponseDto(mail!);
}
private static SentMailResponseDto MapToSentMailResponseDto(SentMail mail)
{
return new SentMailResponseDto
{
Id = mail.Id,
Title = mail.Title,
Content = mail.Content,
SenderId = mail.SenderId,
SenderUsername = mail.Sender?.Username ?? "",
RecipientType = mail.RecipientType,
RecipientId = mail.RecipientId,
RecipientUsername = mail.Recipient?.Username ?? "",
SentAt = mail.SentAt,
DeliveryTime = mail.DeliveryTime,
Status = mail.Status,
StatusText = GetStatusText(mail.Status),
TriggerType = mail.TriggerType,
TriggerTypeText = GetTriggerTypeText(mail.TriggerType),
TriggerDetails = mail.TriggerDetails,
Attachments = mail.Attachments,
IsEncrypted = mail.IsEncrypted,
Theme = mail.Theme,
RecipientTypeText = GetRecipientTypeText(mail.RecipientType),
DaysUntilDelivery = (int)(mail.DeliveryTime - DateTime.UtcNow).TotalDays
};
}
private static ReceivedMailResponseDto MapToReceivedMailResponseDto(ReceivedMail receivedMail)
{
return new ReceivedMailResponseDto
{
Id = receivedMail.Id,
SentMailId = receivedMail.SentMailId,
Title = receivedMail.SentMail.Title,
Content = receivedMail.SentMail.Content,
SenderUsername = receivedMail.SentMail.Sender?.Username ?? "",
SentAt = receivedMail.SentMail.SentAt,
ReceivedAt = receivedMail.ReceivedAt,
IsRead = receivedMail.IsRead,
ReadAt = receivedMail.ReadAt,
IsReplied = receivedMail.IsReplied,
ReplyMailId = receivedMail.ReplyMailId,
Theme = receivedMail.SentMail.Theme
};
}
private static string GetStatusText(int status)
{
return status switch
{
0 => "草稿",
1 => "已发送(待投递)",
2 => "投递中",
3 => "已送达",
_ => "未知"
};
}
private static string GetRecipientTypeText(int recipientType)
{
return recipientType switch
{
0 => "自己",
1 => "指定用户",
2 => "公开时间胶囊",
_ => "未知"
};
}
private static string GetTriggerTypeText(int triggerType)
{
return triggerType switch
{
0 => "时间",
1 => "地点",
2 => "事件",
_ => "未知"
};
}
/// <summary>
/// 发送至未来 - 将草稿状态的邮件设置为在未来特定时间自动发送
/// </summary>
/// <param name="userId">用户ID</param>
/// <param name="sendToFutureDto">发送至未来请求DTO</param>
/// <returns>发送至未来响应DTO</returns>
public async Task<ApiResponse<SendToFutureResponseDto>> SendToFutureAsync(int userId, SendToFutureDto sendToFutureDto)
{
// 检查投递时间是否在未来
if (sendToFutureDto.DeliveryTime <= DateTime.UtcNow)
{
return ApiResponse<SendToFutureResponseDto>.ErrorResult("投递时间必须是未来时间");
}
// 查找邮件
var mail = await _context.SentMails
.Include(m => m.Sender)
.FirstOrDefaultAsync(m => m.Id == sendToFutureDto.MailId && m.SenderId == userId);
if (mail == null)
{
return ApiResponse<SendToFutureResponseDto>.ErrorResult("邮件不存在");
}
// 检查邮件是否为草稿状态
if (mail.Status != 0)
{
return ApiResponse<SendToFutureResponseDto>.ErrorResult("只有草稿状态的邮件可以设置为发送至未来");
}
// 更新邮件状态和投递时间
mail.DeliveryTime = sendToFutureDto.DeliveryTime;
mail.Status = 1; // 设置为已发送(待投递)状态
mail.SentAt = DateTime.UtcNow; // 设置发送时间为当前时间
await _context.SaveChangesAsync();
// 创建时间胶囊
var timeCapsule = new TimeCapsule
{
UserId = userId,
SentMailId = mail.Id,
PositionX = 0,
PositionY = 0,
PositionZ = 0,
Status = 1, // 漂浮中
Type = 0 // 普通
};
_context.TimeCapsules.Add(timeCapsule);
await _context.SaveChangesAsync();
// 构建响应
var response = new SendToFutureResponseDto
{
MailId = mail.Id,
Title = mail.Title,
DeliveryTime = mail.DeliveryTime,
Status = GetStatusText(mail.Status),
SentAt = mail.SentAt
};
return ApiResponse<SendToFutureResponseDto>.SuccessResult(response, "邮件已设置为发送至未来");
}
}
}