928 lines
36 KiB
C#
928 lines
36 KiB
C#
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, "邮件已设置为发送至未来");
|
||
}
|
||
}
|
||
} |